Skip to contentSkip to conversation

x86 Boot enhancements, boot params 1/11

PATCH In review Eric W. Biederman 3 participants 20 messages May 2, 2002 – May 6, 2002

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 x86 Boot enhancements, boot params 1/11

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.

Documentation/i386/zero-page.txt +6 -2
diff -uNr linux-2.5.12/Documentation/i386/zero-page.txt linux-2.5.12.boot.boot_params/Documentation/i386/zero-page.txt
@@ -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.
arch/i386/boot/compressed/misc.c +34 -30

113 lines not on this page · raw message

arch/i386/kernel/setup.c +41 -62

167 lines not on this page · raw message

include/asm-i386/boot_param.h +79 -0

79 lines not on this page · raw message

#1 lore raw

PATCH 1/1 x86 Boot enhancements, linker fixes 2/11

arch/i386/Makefile +1 -1
diff -uNr linux-2.5.12.boot.boot_params/arch/i386/Makefile linux-2.5.12.boot.vmlinuxlds/arch/i386/Makefile
@@ -18,7 +18,7 @@
 
 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
arch/i386/kernel/head.S +1 -1
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
@@ -41,7 +41,7 @@
  *
  * On entry, %esi points to the real-mode code as a 32-bit pointer.
  */
-startup_32:
+ENTRY(startup_32)
 /*
  * Set segments to known values
  */
arch/i386/vmlinux.lds +17 -3
diff -uNr linux-2.5.12.boot.boot_params/arch/i386/vmlinux.lds linux-2.5.12.boot.vmlinuxlds/arch/i386/vmlinux.lds
@@ -3,7 +3,13 @@
  */
 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
 {
   . = 0xC0000000 + 0x100000;
@@ -12,7 +18,7 @@
 	*(.text)
 	*(.fixup)
 	*(.gnu.warning)
-	} = 0x9090
+	} :text = 0x9090
 
   _etext = .;			/* End of text section */
 
@@ -73,8 +79,16 @@
   __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/ : {
#2 lore raw

PATCH 1/1 x86 Boot enhancements, bzImage/zImage code differentiation 3/11

In reply to Eric W. Biederman

Please apply

Differentiate the code that is needed in setup.S for zImage and bzImages.

Eric

arch/i386/boot/setup.S +14 -13
diff -uNr linux-2.5.12.boot.vmlinuxlds/arch/i386/boot/setup.S linux-2.5.12.boot.spring-cleaning/arch/i386/boot/setup.S
@@ -166,7 +166,12 @@
 # End of setup header #####################################################
 
 start_of_setup:
+#ifndef __BIG_KERNEL__
 # Bootlin depends on this being done early
+#NOTE:  Bootlin was written before the kernel had hooks for anything
+# 	used the BIOS calls setup.S made as hooks (ouch!)
+#       Bootlin only loaded zImages, so we can drop support for it
+#       when we are loading a bzImage.
 	movw	$0x01500, %ax
 	movb	$0x81, %dl
 	int	$0x13
@@ -177,6 +182,7 @@
 	movb	$0x80, %dl
 	int	$0x13
 #endif
+#endif /* __BIG_KERNEL__ */
 
 # Set %ds = %cs, we know that SETUPSEG = %cs at this point
 	movw	%cs, %ax		# aka SETUPSEG
@@ -226,6 +232,7 @@
 
 # We now have to find the rest of the setup code/data
 bad_sig:
+#ifndef __BIG_KERNEL__
 	movw	%cs, %ax			# SETUPSEG
 	subw	$DELTA_INITSEG, %ax		# INITSEG
 	movw	%ax, %ds
@@ -255,7 +262,7 @@
 	jne	no_sig
 
 	jmp	good_sig
-
+#endif /* __BIG_KERNEL__ */
 no_sig:
 	lea	no_sig_mess, %si
 	call	prtstr
@@ -268,10 +275,8 @@
 	movw	%cs, %ax			# aka SETUPSEG
 	subw	$DELTA_INITSEG, %ax 		# aka INITSEG
 	movw	%ax, %ds
+#ifdef __BIG_KERNEL__
 # Check if an old loader tries to load a big-kernel
-	testb	$LOADED_HIGH, %cs:loadflags	# Do we have a big kernel?
-	jz	loader_ok			# No, no danger for old loaders.
-
 	cmpb	$0, %cs:type_of_loader 		# Do we have a loader that
 						# can deal with us?
 	jnz	loader_ok			# Yes, continue.
@@ -284,6 +289,7 @@
 	jmp	no_sig_loop
 
 loader_panic_mess: .string "Wrong loader, giving up..."
+#endif /* __BIG_KERNEL__ */
 
 loader_ok:
 # Get memory size (extended mem, kB)
@@ -561,15 +567,8 @@
 	movl	%cs:code32_start, %eax
 	movl	%eax, %cs:code32
 
-# Now we move the system to its rightful place ... but we check if we have a
-# big-kernel. In that case we *must* not move it ...
-	testb	$LOADED_HIGH, %cs:loadflags
-	jz	do_move0			# .. then we have a normal low
-						# loaded zImage
-						# .. or else we have a high
-						# loaded bzImage
-	jmp	end_move			# ... and we skip moving
-
+#ifndef __BIG_KERNEL__
+# Move the kernel image where it expects to be loaded.
 do_move0:
 	movw	$0x100, %ax			# start of destination segment
 	movw	%cs, %bp			# aka SETUPSEG
@@ -595,6 +594,8 @@
 	jb	do_move
 
 end_move:
+#endif /* !__BIG_KERNEL__ */
+	
 # then we load the segment descriptors
 	movw	%cs, %ax			# aka SETUPSEG
 	movw	%ax, %ds
#3 lore raw

Re: [PATCH 2.5.12] x86 Boot enhancements, constants 4/11

In reply to Eric W. Biederman

Please apply,

This patch introduces several constants to the x86 boot process.

Eric

arch/i386/boot/setup.S +8 -7
diff -uNr linux-2.5.12.boot.spring-cleaning/arch/i386/boot/setup.S linux-2.5.12.boot.syntax/arch/i386/boot/setup.S
@@ -59,6 +59,12 @@
 #define SIG1	0xAA55
 #define SIG2	0x5A5A
 
+#ifndef __BIG_KERNEL__
+#define KERNEL_START LOW_BASE		/* zImage */
+#else
+#define KERNEL_START HIGH_BASE 		/* bzImage */
+#endif
+
 INITSEG  = DEF_INITSEG		# 0x9000, we move boot here, out of the way
 SYSSEG   = DEF_SYSSEG		# 0x1000, system loaded at 0x10000 (65536).
 SETUPSEG = DEF_SETUPSEG		# 0x9020, this is the current segment
@@ -118,13 +124,8 @@
 					# loader knows how much data behind
 					# us also needs to be loaded.
 
-code32_start:				# here loaders can put a different
+code32_start:	.long	KERNEL_START	# here loaders can put a different
 					# start address for 32-bit code.
-#ifndef __BIG_KERNEL__
-		.long	0x1000		#   0x1000 = default for zImage
-#else
-		.long	0x100000	# 0x100000 = default for big kernel
-#endif
 
 ramdisk_image:	.long	0		# address of loaded ramdisk image
 					# Here the loader puts the 32-bit
@@ -343,7 +344,7 @@
 
 	incb	(E820NR)
 	movw	%di, %ax
-	addw	$20, %ax
+	addw	$E820ENTRY_SIZE, %ax
 	movw	%ax, %di
 again820:
 	cmpl	$0, %ebx			# check to see if
include/asm-i386/boot.h +13 -0
diff -uNr linux-2.5.12.boot.spring-cleaning/include/asm-i386/boot.h linux-2.5.12.boot.syntax/include/asm-i386/boot.h
@@ -1,6 +1,19 @@
 #ifndef _LINUX_BOOT_H
 #define _LINUX_BOOT_H
 
+/* Address space division during load */
+	/* Memory below 640 we can use for loading */
+#define LOW_BASE   0x001000
+#define LOW_MAX    0x0a0000  /* Maximum low memory address to use */
+	/* Memory above 640 we can use for loading */
+#define HIGH_BASE  0x100000
+#define HIGH_MAX   __MAXMEM
+	/* Subset of the low segment that is generally safe to
+	 * use for loading.
+	 */
+#define REAL_BASE  0x010000
+#define REAL_MAX   0x090000
+
 /* Don't touch these, unless you really know what you're doing. */
 #define DEF_INITSEG	0x9000
 #define DEF_SYSSEG	0x1000
include/asm-i386/e820.h +1 -0
diff -uNr linux-2.5.12.boot.spring-cleaning/include/asm-i386/e820.h linux-2.5.12.boot.syntax/include/asm-i386/e820.h
@@ -15,6 +15,7 @@
 #define E820MAP	0x2d0		/* our map */
 #define E820MAX	32		/* number of entries in E820MAP */
 #define E820NR	0x1e8		/* # entries in E820MAP */
+#define E820ENTRY_SIZE 20	/* size of an E820MAP entry */
 
 #define E820_RAM	1
 #define E820_RESERVED	2
#4 lore raw

PATCH 1/1 x86 Boot enhancements, heap 5/11

In reply to Eric W. Biederman

Please apply,

This patch introduces better heap management into setup.S this allows a compiled in command line to be introduced later on.

Eric

arch/i386/boot/setup.S +15 -17
diff -uNr linux-2.5.12.boot.syntax/arch/i386/boot/setup.S linux-2.5.12.boot.heap/arch/i386/boot/setup.S
@@ -65,6 +65,8 @@
 #define KERNEL_START HIGH_BASE 		/* bzImage */
 #endif
 
+#define DELTA_BOOTSECT 512
+
 INITSEG  = DEF_INITSEG		# 0x9000, we move boot here, out of the way
 SYSSEG   = DEF_SYSSEG		# 0x1000, system loaded at 0x10000 (65536).
 SETUPSEG = DEF_SETUPSEG		# 0x9020, this is the current segment
@@ -73,15 +75,10 @@
 DELTA_INITSEG = SETUPSEG - INITSEG	# 0x0020
 
 .code16
-.globl begtext, begdata, begbss, endtext, enddata, endbss
+.globl _setup, _esetup
 
 .text
-begtext:
-.data
-begdata:
-.bss
-begbss:
-.text
+_setup:	
 
 start:
 	jmp	trampoline
@@ -137,7 +134,7 @@
 bootsect_kludge:
 		.word  bootsect_helper, SETUPSEG
 
-heap_end_ptr:	.word	modelist+1024	# (Header version 0x0201 or later)
+heap_end_ptr:	.word	_esetup_heap	# (Header version 0x0201 or later)
 					# space from here (exclusive) down to
 					# end of setup code can be used by setup
 					# for local heap purposes.
@@ -162,8 +159,12 @@
 					# The highest safe address for
 					# the contents of an initrd
 
+# variables private to setup.S (not for bootloaders)
+real_filesz:				# Datasize of the real mode kernel
+		.long (_esetup - _setup) + DELTA_BOOTSECT
 trampoline:	call	start_of_setup
-		.space	1024
+		# Don't let the E820 map overlap code
+		. = (E820MAP - DELTA_BOOTSECT) + (E820MAX * E820ENTRY_SIZE)
 # End of setup header #####################################################
 
 start_of_setup:
@@ -1042,11 +1043,8 @@
 # After this point, there is some free space which is used by the video mode
 # handling code to store the temporary mode table (not used by the kernel).
 
-modelist:
-
-.text
-endtext:
-.data
-enddata:
-.bss
-endbss:
+_esetup:
+.section ".setup.heap", "a", @nobits
+_setup_heap:
+. = DEF_HEAP_SIZE
+_esetup_heap:
arch/i386/boot/video.S +22 -11
diff -uNr linux-2.5.12.boot.syntax/arch/i386/boot/video.S linux-2.5.12.boot.heap/arch/i386/boot/video.S
@@ -117,6 +117,12 @@
 	xorw	%ax, %ax
 	movw	%ax, %gs	# GS is zero
 	cld
+
+	# Setup the heap
+	movl	real_filesz, %eax
+	subl	$DELTA_BOOTSECT, %eax
+	movw	%ax, heap_start
+	
 	call	basic_detect	# Basic adapter type testing (EGA/VGA/MDA/CGA)
 #ifdef CONFIG_VIDEO_SELECT
 	movw	%fs:(0x01fa), %ax		# User selected video mode
@@ -201,7 +207,7 @@
 #ifdef CONFIG_VIDEO_SELECT
 # Fetching of VESA frame buffer parameters
 mopar_gr:
-	leaw	modelist+1024, %di
+	movw	heap_start, %di
 	movb	$0x23, %fs:(PARAM_HAVE_VGA)
 	movw	16(%di), %ax
 	movw	%ax, %fs:(PARAM_LFB_LINELENGTH)
@@ -223,7 +229,7 @@
 	movl	%eax, %fs:(PARAM_LFB_COLORS+4)
 
 # get video mem size
-	leaw	modelist+1024, %di
+	movw	heap_start, %di
 	movw	$0x4f00, %ax
 	int	$0x10
 	xorl	%eax, %eax
@@ -284,7 +290,7 @@
 	leaw	listhdr, %si			# Table header
 	call	prtstr
 	movb	$0x30, %dl			# DL holds mode number
-	leaw	modelist, %si
+	movw	modelist, %si
 lm1:	cmpw	$ASK_VGA, (%si)			# End?
 	jz	lm2
 
@@ -529,7 +535,7 @@
 	jmp	_m_s
 
 check_vesa:
-	leaw	modelist+1024, %di
+	movw	heap_start, %di
 	subb	$VIDEO_FIRST_VESA>>8, %bh
 	movw	%bx, %cx			# Get mode information structure
 	movw	$0x4f01, %ax
@@ -774,12 +780,13 @@
 	mulb	%ah
 	movw	%ax, %cx			# CX=number of characters
 	addw	%ax, %ax			# Calculate image size
-	addw	$modelist+1024+4, %ax
+	addw	heap_start, %ax
+	addw	$4, %ax
 	cmpw	heap_end_ptr, %ax
 	jnc	sts1				# Unfortunately, out of memory
 
 	movw	%fs:(PARAM_CURSOR_POS), %ax	# Store mode params
-	leaw	modelist+1024, %di
+	movw	heap_start, %di
 	stosw
 	movw	%bx, %ax
 	stosw
@@ -802,7 +809,7 @@
 	call	mode_params			# Get parameters of current mode
 	movb	%fs:(PARAM_VIDEO_LINES), %cl
 	movb	%fs:(PARAM_VIDEO_COLS), %ch
-	leaw	modelist+1024, %si		# Screen buffer
+	movw	heap_start, %si			# Screen buffer
 	lodsw					# Set cursor position
 	movw	%ax, %dx
 	cmpb	%cl, %dh
@@ -883,7 +890,8 @@
 	orw	%di, %di
 	jnz	mtab1x
 	
-	leaw	modelist, %di			# Store standard modes:
+	movw	heap_start, %di			# Store standard modes:
+	movw	%di, modelist
 	movl	$VIDEO_80x25 + 0x50190000, %eax	# The 80x25 mode (ALL)
 	stosl
 	movb	adapter, %al			# CGA/MDA/HGA -- no more modes
@@ -929,13 +937,13 @@
 mtabe:
 
 #ifdef CONFIG_VIDEO_COMPACT
-	leaw	modelist, %si
+	movw	modelist, %si
 	movw	%di, %dx
 	movw	%si, %di
 cmt1:	cmpw	%dx, %si			# Scan all modes
 	jz	cmt2
 
-	leaw	modelist, %bx			# Find in previous entries
+	movw	modelist, %bx			# Find in previous entries
 	movw	2(%si), %cx
 cmt3:	cmpw	%bx, %si
 	jz	cmt4
@@ -957,7 +965,8 @@
 
 	movw	$ASK_VGA, (%di)			# End marker
 	movw	%di, mt_end
-mtab1:	leaw	modelist, %si			# SI=mode list, DI=list end
+	movw	%di, heap_start
+mtab1:	movw	modelist, %si			# SI=mode list, DI=list end
 ret0:	ret
 
 # Modes usable on all standard VGAs
@@ -1932,3 +1941,5 @@
 adapter:	.byte	0	# Video adapter: 0=CGA/MDA/HGA,1=EGA,2=VGA
 video_segment:	.word	0xb800	# Video memory segment
 force_size:	.word	0	# Use this size instead of the one in BIOS vars
+modelist:	.word	0	# Start of modelist on the heap
+heap_start:	.word	0	# low heap address
include/asm-i386/boot.h +1 -0
diff -uNr linux-2.5.12.boot.syntax/include/asm-i386/boot.h linux-2.5.12.boot.heap/include/asm-i386/boot.h
@@ -19,6 +19,7 @@
 #define DEF_SYSSEG	0x1000
 #define DEF_SETUPSEG	0x9020
 #define DEF_SYSSIZE	0x7F00
+#define DEF_HEAP_SIZE	1024
 
 /* Internal svga startup constants */
 #define NORMAL_VGA	0xffff		/* 80x25 mode */
include/asm-i386/boot_param.h +3 -1
diff -uNr linux-2.5.12.boot.syntax/include/asm-i386/boot_param.h linux-2.5.12.boot.heap/include/asm-i386/boot_param.h
@@ -72,7 +72,9 @@
 	__u32 cmd_line_ptr;			/* 0x228 */
 	/* 2.03+ */
 	__u32 ramdisk_max;			/* 0x22c */
-	__u8  reserved15[0x2d0 - 0x230];	/* 0x230 */
+	/* Below this point for internal kernel use only */
+	__u32 real_filesz;			/* 0x230 */
+	__u8  reserved15[0x2d0 - 0x234];	/* 0x234 */
 	struct e820entry e820_map[E820MAX];	/* 0x2d0 */
 						/* 0x550 */
 } __attribute__((packed));
#5 lore raw

Re: [PATCH 2.5.12] x86 Boot enhancements, 32bit entries 6/11

In reply to Eric W. Biederman

Please apply,

This patch cleans up the 32bit kernel entry points so they don't assume who their caller is, making them usable by other than setup.S

For arch/i386/kernel/head.S this untangles the secondary cpu and the bootstrap entry points making the code more readable.

Eric

arch/i386/boot/compressed/head.S +72 -28
diff -uNr linux-2.5.12.boot.heap/arch/i386/boot/compressed/head.S linux-2.5.12.boot.clean_32bit_entries/arch/i386/boot/compressed/head.S
@@ -25,24 +25,30 @@
 
 #include <linux/linkage.h>
 #include <asm/segment.h>
+#include <asm/boot.h>
 
 	.globl startup_32
 	
 startup_32:
 	cld
 	cli
-	movl $(__KERNEL_DS),%eax
-	movl %eax,%ds
-	movl %eax,%es
-	movl %eax,%fs
-	movl %eax,%gs
 
-	lss stack_start,%esp
-	xorl %eax,%eax
-1:	incl %eax		# check that A20 really IS enabled
-	movl %eax,0x000000	# loop forever if it isn't
-	cmpl %eax,0x100000
-	je 1b
+	/*
+	 * Save the initial registers
+	 */
+	movl %eax, eax
+	movl %ebx, ebx
+	movl %ecx, ecx
+	movl %edx, edx
+	movl %esi, esi
+	movl %edi, edi
+	movl %esp, esp
+	movl %ebp, ebp
+
+	/*
+	 * Setup the stack
+	 */
+	movl stack_start, %esp
 
 /*
  * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
@@ -66,16 +72,10 @@
  */
 	subl $16,%esp	# place for structure on the stack
 	movl %esp,%eax
-	pushl %esi	# real mode pointer as second arg
 	pushl %eax	# address of structure as first arg
 	call decompress_kernel
-	orl  %eax,%eax 
-	jnz  3f
-	popl %esi	# discard address
-	popl %esi	# real mode pointer
-	xorl %ebx,%ebx
-	ljmp $(__KERNEL_CS), $0x100000
-
+	orl  %eax,%eax
+	jz out
 /*
  * We come here, if we were loaded high.
  * We need to move the move-in-place routine down to 0x1000
@@ -83,8 +83,21 @@
  * which we got from the stack.
  */
 3:
-	movl $move_routine_start,%esi
-	movl $0x1000,%edi
+	/* Relocate the move routine */
+	movl $move_routine_start,%esi	#src
+	movl %eax,%edi			#dest
+	movl %eax, %ebp                 #saved dest
+	movl %edi, %eax 
+	subl %esi, %eax			# The relocation factor
+	addl %eax, reloc1
+	addl %eax, reloc2
+	addl %eax, reloc3
+	addl %eax, reloc4
+	addl %eax, reloc5
+	addl %eax, reloc6
+	addl %eax, reloc7
+	addl %eax, reloc8
+	addl %eax, reloc9
 	movl $move_routine_end,%ecx
 	subl %esi,%ecx
 	addl $3,%ecx
@@ -93,20 +106,23 @@
 	rep
 	movsl
 
+	/* Load it's arguments and jump to the move routine */
 	popl %esi	# discard the address
-	popl %ebx	# real mode pointer
 	popl %esi	# low_buffer_start
 	popl %ecx	# lcount
 	popl %edx	# high_buffer_start
 	popl %eax	# hcount
-	movl $0x100000,%edi
+	movl $HIGH_BASE,%edi
 	cli		# make sure we don't get interrupted
-	ljmp $(__KERNEL_CS), $0x1000 # and jump to the move routine
+	jmpl *%ebp
 
 /*
  * Routine (template) for moving the decompressed kernel in place,
- * if we were high loaded. This _must_ PIC-code !
+ * if we were high loaded. This _must_ be PIC-code !
+ * Or it must be anotated with lables so it can be manually relocated.
  */
+	.globl move_routine_start, move_routine_end
+	.balign 4
 move_routine_start:
 	movl %ecx,%ebp
 	shrl $2,%ecx
@@ -122,7 +138,35 @@
 	shrl $2,%ecx
 	rep
 	movsl
-	movl %ebx,%esi	# Restore setup pointer
-	xorl %ebx,%ebx
-	ljmp $(__KERNEL_CS), $0x100000
+out:
+	.byte 0xa1		# movl eax,  %eax
+reloc1:	.long eax
+	.byte 0x8b, 0x1d	# movl ebx,  %ebx
+reloc2:	.long ebx
+	.byte 0x8b, 0x0d	# movl ecx,  %ecx
+reloc3:	.long ecx
+	.byte 0x8b, 0x15	# movl edx, %edx
+reloc4:	.long edx
+	.byte 0x8b, 0x35	# movl esi, %esi
+reloc5:	.long esi
+	.byte 0x8b, 0x3d	# movl edi, %edi
+reloc6:	.long edi
+	.byte 0x8b, 0x25	# movl esp, %esp
+reloc7:	.long esp
+	.byte 0x8b, 0x2d	# movl ebp, %ebp
+reloc8:	.long ebp
+	.byte 0xff, 0x25	# jmpl *(kernel_start)
+reloc9:	.long kernel_start
+	.balign 4
+ENTRY(initial_regs)
+eax:	.long 0x12345678 /* eax */
+ebx:	.long 0x12345678 /* ebx */
+ecx:	.long 0x12345678 /* ecx */
+edx:	.long 0x12345678 /* edx */
+esi:	.long 0x12345678 /* esi */
+edi:	.long 0x12345678 /* edi */
+esp:	.long 0x12345678 /* esp */
+ebp:	.long 0x12345678 /* ebp */
+kernel_start:
+	.long HIGH_BASE
 move_routine_end:
arch/i386/boot/compressed/misc.c +40 -21

124 lines not on this page · raw message

arch/i386/boot/setup.S +18 -3
diff -uNr linux-2.5.12.boot.heap/arch/i386/boot/setup.S linux-2.5.12.boot.clean_32bit_entries/arch/i386/boot/setup.S
@@ -67,6 +67,12 @@
 
 #define DELTA_BOOTSECT 512
 
+/* Segments used by setup.S */
+#define __SETUP_CS      0x10
+#define __SETUP_DS      0x18
+#define __SETUP_REAL_CS 0x20
+#define __SETUP_REAL_DS 0x28
+
 INITSEG  = DEF_INITSEG		# 0x9000, we move boot here, out of the way
 SYSSEG   = DEF_SYSSEG		# 0x1000, system loaded at 0x10000 (65536).
 SETUPSEG = DEF_SETUPSEG		# 0x9020, this is the current segment
@@ -798,13 +804,22 @@
 	jmp	flush_instr
 
 flush_instr:
-	xorw	%bx, %bx			# Flag to indicate a boot
 	xorl	%esi, %esi			# Pointer to real-mode code
 	movw	%cs, %si
 	subw	$DELTA_INITSEG, %si
 	shll	$4, %esi			# Convert to 32-bit pointer
+	movl	$ENTRY16, %ebp			# Magic to indicate 16bit entry
+
+# Setup the data segments
+	movw	$(__SETUP_DS), %ax
+	movw	%ax, %ds
+	movw	%ax, %es
+	movw	%ax, %fs
+	movw	%ax, %gs
+	movw	%ax, %ss
+
 # NOTE: For high loaded big kernels we need a
-#	jmpi    0x100000,__KERNEL_CS
+#	jmpi    0x100000,__SETUP_CS
 #
 #	but we yet haven't reloaded the CS register, so the default size 
 #	of the target offset still is 16 bit.
@@ -815,7 +830,7 @@
 	.byte 0x66, 0xea			# prefix + jmpi-opcode
 code32:	.long	0x1000				# will be set to 0x100000
 						# for big kernels
-	.word	__KERNEL_CS
+	.word	__SETUP_CS
 
 # Here's a bunch of information about your current kernel..
 kernel_version:	.ascii	UTS_RELEASE
arch/i386/kernel/head.S +99 -102

259 lines not on this page · raw message

arch/i386/kernel/setup.c +90 -22

163 lines not on this page · raw message

arch/i386/kernel/trampoline.S +9 -9
diff -uNr linux-2.5.12.boot.heap/arch/i386/kernel/trampoline.S linux-2.5.12.boot.clean_32bit_entries/arch/i386/kernel/trampoline.S
@@ -12,10 +12,6 @@
  *	In fact we don't actually need a stack so we don't
  *	set one up.
  *
- *	We jump into the boot/compressed/head.S code. So you'd
- *	better be running a compressed kernel image or you
- *	won't get very far.
- *
  *	On entry to trampoline_data, the processor is in real mode
  *	with 16-bit addressing and 16-bit data.  CS has some value
  *	and IP is zero.  Thus, data addresses need to be absolute
@@ -23,12 +19,16 @@
  *
  *	If you work on this file, check the object module with objdump
  *	--full-contents --reloc to make sure there are no relocation
- *	entries except for the gdt one..
+ *	entries except for gdt & secondary_startup_32..
  */
 
 #include <linux/linkage.h>
+#include <linux/threads.h>
 #include <asm/segment.h>
 #include <asm/page.h>
+#include <asm/desc.h>
+
+#define GDT_ENTRIES	(__TSS(NR_CPUS))
 
 .data
 
@@ -42,7 +42,6 @@
 	mov	%cs, %ax	# Code and data in the same place
 	mov	%ax, %ds
 
-	mov	$1, %bx		# Flag an SMP trampoline
 	cli			# We should be safe anyway
 
 	movl	$0xA5A5A5A5, trampoline_data - r_base
@@ -56,15 +55,16 @@
 	lmsw	%ax		# into protected mode
 	jmp	flush_instr
 flush_instr:
-	ljmpl	$__KERNEL_CS, $0x00100000
-			# jump to startup_32 in arch/i386/kernel/head.S
+		# jump to secondary_startup_32 in arch/i386/kernel/head.S
+	ljmpl	$__KERNEL_CS, $(secondary_startup_32 - __PAGE_OFFSET)
+	
 
 idt_48:
 	.word	0			# idt limit = 0
 	.word	0, 0			# idt base = 0L
 
 gdt_48:
-	.word	0x0800			# gdt limit = 2048, 256 GDT entries
+	.word	GDT_ENTRIES*8-1		# gdt limit
 	.long	gdt_table-__PAGE_OFFSET	# gdt base = gdt (first SMP CPU)
 
 .globl trampoline_end
include/asm-i386/boot.h +10 -0
diff -uNr linux-2.5.12.boot.heap/include/asm-i386/boot.h linux-2.5.12.boot.clean_32bit_entries/include/asm-i386/boot.h
@@ -26,4 +26,14 @@
 #define EXTENDED_VGA	0xfffe		/* 80x50 mode */
 #define ASK_VGA		0xfffd		/* ask for it at bootup */
 
+/* Entry point ID constants */
+#define ENTRY16		0x73726468 /* 'hdrs' */
+#define ENTRY32		0x53524448 /* 'HDRS' */
+
+/* Maximum command line size */
+#define COMMAND_LINE_SIZE 256
+
+/* Initial page table size 8MB */
+#define INITIAL_PAGE_TABLE_SIZE 0x800000
+
 #endif
include/asm-i386/boot_param.h +10 -0
diff -uNr linux-2.5.12.boot.heap/include/asm-i386/boot_param.h linux-2.5.12.boot.clean_32bit_entries/include/asm-i386/boot_param.h
@@ -1,6 +1,16 @@
 #ifndef __I386_BOOT_PARAM_H
 #define __I386_BOOT_PARAM_H
 
+struct initial_regs32 {
+	const __u32 eax;
+	const __u32 ebx;
+	const __u32 ecx;
+	const __u32 edx;
+	const __u32 esi;
+	const __u32 edi;
+	const __u32 esp;
+	const __u32 ebp;
+}; 
 struct drive_info_struct { __u8 dummy[32]; };
 struct sys_desc_table {
 	__u16 length;
#6 lore raw

PATCH 1/1 x86 Boot enhancements, footprint reduction 7/11

In reply to Eric W. Biederman

Please apply,

This reduces the boot footprint of the Linux kernel by making the kernel decompressor an inplace algorithm, making bzImages more efficient with memory than zImages.

It fixes the bug of asking bootloaders to make a tradeoff between reliability and memory efficiency.

Eric

arch/i386/boot/compressed/Makefile +3 -5
diff -uNr linux-2.5.12.boot.clean_32bit_entries/arch/i386/boot/compressed/Makefile linux-2.5.12.boot.footprint/arch/i386/boot/compressed/Makefile
@@ -9,8 +9,6 @@
 
 OBJECTS = $(HEAD) misc.o
 
-ZLDFLAGS = -e startup_32
-
 #
 # ZIMAGE_OFFSET is the load offset of the compression loader
 # BZIMAGE_OFFSET is the load offset of the high loaded compression loader
@@ -18,8 +16,8 @@
 ZIMAGE_OFFSET = 0x1000
 BZIMAGE_OFFSET = 0x100000
 
-ZLINKFLAGS = -Ttext $(ZIMAGE_OFFSET) $(ZLDFLAGS)
-BZLINKFLAGS = -Ttext $(BZIMAGE_OFFSET) $(ZLDFLAGS)
+ZLINKFLAGS = -Ttext $(ZIMAGE_OFFSET) -T vmlinuz.lds
+BZLINKFLAGS = -Ttext $(BZIMAGE_OFFSET) -T vmlinuz.lds 
 
 all: vmlinux
 
@@ -42,7 +40,7 @@
 	rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk; \
 	$(OBJCOPY) $(SYSTEM) $$tmppiggy; \
 	gzip -f -9 < $$tmppiggy > $$tmppiggy.gz; \
-	echo "SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}" > $$tmppiggy.lnk; \
+	echo "SECTIONS { .input : { *(.data) }}" > $$tmppiggy.lnk; \
 	$(LD) -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-i386 -T $$tmppiggy.lnk; \
 	rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk
 
arch/i386/boot/compressed/head.S +26 -0
diff -uNr linux-2.5.12.boot.clean_32bit_entries/arch/i386/boot/compressed/head.S linux-2.5.12.boot.footprint/arch/i386/boot/compressed/head.S
@@ -30,6 +30,20 @@
 	.globl startup_32
 	
 startup_32:
+	jmp 1f
+	.balign		4
+	.globl input_addr, input_len, output_overhang
+	.globl kernel_base, kernel_memsz, kernel_filesz
+	.globl unzip_memsz, unzip_filesz
+input_addr:		.long input_data
+input_len:		.long input_data_len
+output_overhang:	.long input_data_len # Will be set to 8 later...
+kernel_base:		.long HIGH_BASE
+kernel_memsz:		.long 0
+kernel_filesz:		.long 0
+unzip_memsz:		.long _end
+unzip_filesz:		.long _edata
+1:	
 	cld
 	cli
 
@@ -44,6 +58,18 @@
 	movl %edi, edi
 	movl %esp, esp
 	movl %ebp, ebp
+
+	/* 
+	 * Move the input data off the bss segment
+	 */
+	std
+	movl $input_data_end -1, %esi
+	movl %esi, %edi
+	addl $input_data_shift, %edi
+	movl $input_data_len, %ecx
+	rep movsb
+	cld
+	addl $input_data_shift, input_addr
 
 	/*
 	 * Setup the stack
arch/i386/boot/compressed/misc.c +123 -65

288 lines not on this page · raw message

arch/i386/boot/compressed/vmlinuz.lds +29 -0
diff -uNr linux-2.5.12.boot.clean_32bit_entries/arch/i386/boot/compressed/vmlinuz.lds linux-2.5.12.boot.footprint/arch/i386/boot/compressed/vmlinuz.lds
@@ -0,0 +1,29 @@
+/* ld script to make compressed i386 Linux kernel
+ */
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(startup_32)
+SECTIONS
+{
+	. = 0x1000;
+	_text = .;			/* Text and read-only data */
+	.text : { *(.text) } = 0x9090
+	_etext = .;			/* End of text section */
+	.rodata : { *(.rodata) *(.rodata.*) }
+	.data : { 
+		*(.data) 
+		
+	}
+	_edata = .;			/* End of data section */
+	.bss _edata : { *(.bss) }
+	_end = .;
+	.input _edata : { 
+		input_data = . ;
+		*(.input)
+		input_data_end = . ;
+	}
+	input_data_len = input_data_end - input_data;
+	input_data_shift = _end - _edata;
+
+	/DISCARD/ : { *(*) }
+}		
arch/i386/boot/setup.S +21 -4
diff -uNr linux-2.5.12.boot.clean_32bit_entries/arch/i386/boot/setup.S linux-2.5.12.boot.footprint/arch/i386/boot/setup.S
@@ -109,6 +109,8 @@
 # flags, unused bits must be zero (RFU) bit within loadflags
 loadflags:
 LOADED_HIGH	= 1			# If set, the kernel is loaded high
+STAY_PUT        = 0x40                  # If set, the loader doesn't expect
+                                        # us to relocate anything
 CAN_USE_HEAP	= 0x80			# If set, the loader also has set
 					# heap_end_ptr to tell how much
 					# space behind setup.S can be used for
@@ -165,7 +167,11 @@
 					# The highest safe address for
 					# the contents of an initrd
 
-# variables private to setup.S (not for bootloaders)
+# variables private to the kernel (not for bootloaders)
+pad2:		.long	0
+real_base:	.long	REAL_BASE	# Location of real mode kernel
+real_memsz:				# Memory usage of real mode kernel
+		.long	(_esetup_heap - _setup) + DELTA_BOOTSECT
 real_filesz:				# Datasize of the real mode kernel
 		.long (_esetup - _setup) + DELTA_BOOTSECT
 trampoline:	call	start_of_setup
@@ -300,6 +306,15 @@
 #endif /* __BIG_KERNEL__ */
 
 loader_ok:
+# Get base memory size
+# The size in kilobytes is returned in %ax
+# There shouldn't be any subfunctions but just
+# in case we clear eax and ecx
+	xorl	%eax, %eax
+	xorl	%ecx, %ecx
+	int	$0x12
+	movw	%ax, (0x1e4)
+	
 # Get memory size (extended mem, kB)
 
 	xorl	%eax, %eax
@@ -607,12 +622,13 @@
 # then we load the segment descriptors
 	movw	%cs, %ax			# aka SETUPSEG
 	movw	%ax, %ds
-		
+
 # Check whether we need to be downward compatible with version <=201
+# We don't relocate if STAY_PUT is specified or we have a 202 cmd_line
+	testb  	$STAY_PUT, loadflags
+	jnz	end_move_self
 	cmpl	$0, cmd_line_ptr
 	jne	end_move_self		# loader uses version >=202 features
-	cmpb	$0x20, type_of_loader
-	je	end_move_self		# bootsect loader, we know of it
 
 # Boot loader doesnt support boot protocol version 2.02.
 # If we have our code not at 0x90000, we need to move it there now.
@@ -860,6 +876,7 @@
 	jnz	bootsect_second
 
 	movb	$0x20, %cs:type_of_loader
+	orb	$STAY_PUT, %cs:loadflags
 	movw	%es, %ax
 	shrw	$4, %ax
 	movb	%ah, %cs:bootsect_src_base+2
arch/i386/boot/tools/build.c +157 -6

191 lines not on this page · raw message

include/asm-i386/boot_param.h +7 -3
diff -uNr linux-2.5.12.boot.clean_32bit_entries/include/asm-i386/boot_param.h linux-2.5.12.boot.footprint/include/asm-i386/boot_param.h
@@ -37,7 +37,8 @@
 	struct drive_info_struct drive_info;	/* 0x80 */
 	struct sys_desc_table sys_desc_table;	/* 0xa0 */
 	__u32 alt_mem_k;			/* 0x1e0 */
-	__u8  reserved5[4];			/* 0x1e4 */
+	__u16 base_mem_k;			/* 0x1e4 */
+	__u8  reserved5[2];			/* 0x1e6 */
 	__u8  e820_map_nr;			/* 0x1e8 */
 	__u8  reserved6[8];			/* 0x1e9 */
 	__u8  setup_sects;			/* 0x1f1 */
@@ -83,8 +84,11 @@
 	/* 2.03+ */
 	__u32 ramdisk_max;			/* 0x22c */
 	/* Below this point for internal kernel use only */
-	__u32 real_filesz;			/* 0x230 */
-	__u8  reserved15[0x2d0 - 0x234];	/* 0x234 */
+	__u32 pad2;				/* 0x230 */
+	__u32 real_base;			/* 0x234 */
+	__u32 real_memsz;			/* 0x238 */
+	__u32 real_filesz;			/* 0x23c */
+	__u8  reserved15[0x2d0 - 0x240];	/* 0x240 */
 	struct e820entry e820_map[E820MAX];	/* 0x2d0 */
 						/* 0x550 */
 } __attribute__((packed));
#7 lore raw

PATCH 1/1 x86 Boot enhancements, build beancounting 8/11

In reply to Eric W. Biederman

Please apply,

This patch reorganizes the build of the x86 boot image so that we preserve enough information to accurately track how much memory will be used.

Eric

Makefile +0 -9
diff -uNr linux-2.5.12.boot.footprint/Makefile linux-2.5.12.boot.build/Makefile
@@ -93,15 +93,6 @@
 AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS)
 
 #
-# ROOT_DEV specifies the default root-device when making the image.
-# This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case
-# the default of FLOPPY is used by 'build'.
-# This is i386 specific.
-#
-
-export ROOT_DEV = CURRENT
-
-#
 # If you want to preset the SVGA mode, uncomment the next line and
 # set SVGA_MODE to whatever number you want.
 # Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode.
arch/i386/boot/Makefile +14 -22
diff -uNr linux-2.5.12.boot.footprint/arch/i386/boot/Makefile linux-2.5.12.boot.build/arch/i386/boot/Makefile
@@ -12,13 +12,11 @@
 		$(TOPDIR)/include/linux/autoconf.h \
 		$(TOPDIR)/include/asm/boot.h
 
-zImage: $(CONFIGURE) bootsect setup compressed/vmlinux tools/build
-	$(OBJCOPY) compressed/vmlinux compressed/vmlinux.out
-	tools/build bootsect setup compressed/vmlinux.out $(ROOT_DEV) > zImage
-
-bzImage: $(CONFIGURE) bbootsect bsetup compressed/bvmlinux tools/build
-	$(OBJCOPY) compressed/bvmlinux compressed/bvmlinux.out
-	tools/build -b bbootsect bsetup compressed/bvmlinux.out $(ROOT_DEV) > bzImage
+zImage: $(CONFIGURE) tools/build $(TOPDIR)/vmlinux realmode compressed/vmlinux 
+	tools/build $(TOPDIR)/vmlinux realmode compressed/vmlinux zImage
+
+bzImage: $(CONFIGURE) tools/build $(TOPDIR)/vmlinux brealmode compressed/bvmlinux 
+	tools/build -b $(TOPDIR)/vmlinux brealmode compressed/bvmlinux bzImage
 
 compressed/vmlinux: $(TOPDIR)/vmlinux
 	@$(MAKE) -C compressed vmlinux
@@ -39,49 +37,43 @@
 install: $(CONFIGURE) $(BOOTIMAGE)
 	sh -x ./install.sh $(KERNELRELEASE) $(BOOTIMAGE) $(TOPDIR)/System.map "$(INSTALL_PATH)"
 
-tools/build: tools/build.c
+tools/build: tools/build.c $(TOPDIR)/include/linux/version.h $(TOPDIR)/include/linux/compile.h $(TOPDIR)/include/asm-i386/boot.h
 	$(HOSTCC) $(HOSTCFLAGS) -o $@ $< -I$(TOPDIR)/include
 
-bootsect: bootsect.o
-	$(LD) -Ttext 0x0 -s --oformat binary -o $@ $<
-
 bootsect.o: bootsect.s
 	$(AS) -o $@ $<
 
 bootsect.s: bootsect.S Makefile $(BOOT_INCL)
 	$(CPP) $(CPPFLAGS) -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@
 
-bbootsect: bbootsect.o
-	$(LD) -Ttext 0x0 -s --oformat binary $< -o $@
-
 bbootsect.o: bbootsect.s
 	$(AS) -o $@ $<
 
 bbootsect.s: bootsect.S Makefile $(BOOT_INCL)
 	$(CPP) $(CPPFLAGS) -D__BIG_KERNEL__ -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@
 
-setup: setup.o
-	$(LD) -Ttext 0x0 -s --oformat binary -e begtext -o $@ $<
-
 setup.o: setup.s
 	$(AS) -o $@ $<
 
 setup.s: setup.S video.S Makefile $(BOOT_INCL) $(TOPDIR)/include/linux/version.h $(TOPDIR)/include/linux/compile.h
 	$(CPP) $(CPPFLAGS) -D__ASSEMBLY__ -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@
 
-bsetup: bsetup.o
-	$(LD) -Ttext 0x0 -s --oformat binary -e begtext -o $@ $<
-
 bsetup.o: bsetup.s
 	$(AS) -o $@ $<
 
 bsetup.s: setup.S video.S Makefile $(BOOT_INCL) $(TOPDIR)/include/linux/version.h $(TOPDIR)/include/linux/compile.h
 	$(CPP) $(CPPFLAGS) -D__BIG_KERNEL__ -D__ASSEMBLY__ -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@
 
+realmode: bootsect.o setup.o
+	$(LD) -T realmode.lds -o $@ $^
+
+brealmode: bbootsect.o bsetup.o
+	$(LD) -T realmode.lds -o $@ $^
+
 dep:
 
 clean:
 	rm -f tools/build
-	rm -f setup bootsect zImage compressed/vmlinux.out
-	rm -f bsetup bbootsect bzImage compressed/bvmlinux.out
+	rm -f realmode zImage
+	rm -f brealmode bzImage
 	@$(MAKE) -C compressed clean
arch/i386/boot/bootsect.S +1 -1
diff -uNr linux-2.5.12.boot.footprint/arch/i386/boot/bootsect.S linux-2.5.12.boot.build/arch/i386/boot/bootsect.S
@@ -54,7 +54,7 @@
 #endif
 
 .code16
-.text
+.section ".bootsect", "ax", @progbits
 
 .global _start
 _start:
arch/i386/boot/realmode.lds +18 -0
diff -uNr linux-2.5.12.boot.footprint/arch/i386/boot/realmode.lds linux-2.5.12.boot.build/arch/i386/boot/realmode.lds
@@ -0,0 +1,18 @@
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+ENTRY(_start)
+OUTPUT_ARCH(i386)
+SECTIONS
+{
+	.bootsect 0 : AT(0x10000) {
+		*(.bootsect)
+	}
+	.setup 0 : AT(LOADADDR(.bootsect) + SIZEOF(.bootsect)) {
+		*(.setup)
+	}
+	.setup.heap SIZEOF(.setup) : AT(LOADADDR(.setup) + SIZEOF(.setup)) {
+		*(.setup.heap)
+	}
+	/DISCARD/ : {
+		*(*)
+	}
+}
arch/i386/boot/setup.S +4 -1
diff -uNr linux-2.5.12.boot.footprint/arch/i386/boot/setup.S linux-2.5.12.boot.build/arch/i386/boot/setup.S
@@ -83,7 +83,7 @@
 .code16
 .globl _setup, _esetup
 
-.text
+.section ".setup", "ax", @progbits
 _setup:	
 
 start:
@@ -174,6 +174,9 @@
 		.long	(_esetup_heap - _setup) + DELTA_BOOTSECT
 real_filesz:				# Datasize of the real mode kernel
 		.long (_esetup - _setup) + DELTA_BOOTSECT
+kern_base:	.long	KERNEL_START	# Kernel load address
+kern_memsz:	.long	0x00000000	# Kernel memory usage
+kern_filesz:	.long	0x00000000	# Kernel datasize
 trampoline:	call	start_of_setup
 		# Don't let the E820 map overlap code
 		. = (E820MAP - DELTA_BOOTSECT) + (E820MAX * E820ENTRY_SIZE)
arch/i386/boot/tools/build.c +513 -147

759 lines not on this page · raw message

arch/x86_64/boot/Makefile +2 -2
diff -uNr linux-2.5.12.boot.footprint/arch/x86_64/boot/Makefile linux-2.5.12.boot.build/arch/x86_64/boot/Makefile
@@ -14,11 +14,11 @@
 
 zImage: $(CONFIGURE) bootsect setup compressed/vmlinux tools/build
 	$(OBJCOPY) compressed/vmlinux compressed/vmlinux.out
-	tools/build bootsect setup compressed/vmlinux.out $(ROOT_DEV) > zImage
+	tools/build bootsect setup compressed/vmlinux.out CURRENT > zImage
 
 bzImage: $(CONFIGURE) bbootsect bsetup compressed/bvmlinux tools/build
 	$(OBJCOPY) compressed/bvmlinux compressed/bvmlinux.out
-	tools/build -b bbootsect bsetup compressed/bvmlinux.out $(ROOT_DEV) > bzImage
+	tools/build -b bbootsect bsetup compressed/bvmlinux.out CURRENT > bzImage
 
 bzImage-padded: bzImage
 	dd if=/dev/zero bs=1k count=70 >> bzImage
include/asm-i386/boot_param.h +4 -1
diff -uNr linux-2.5.12.boot.footprint/include/asm-i386/boot_param.h linux-2.5.12.boot.build/include/asm-i386/boot_param.h
@@ -88,7 +88,10 @@
 	__u32 real_base;			/* 0x234 */
 	__u32 real_memsz;			/* 0x238 */
 	__u32 real_filesz;			/* 0x23c */
-	__u8  reserved15[0x2d0 - 0x240];	/* 0x240 */
+ 	__u32 kern_base;			/* 0x240 */
+ 	__u32 kern_memsz;			/* 0x244 */
+ 	__u32 kern_filesz;			/* 0x248 */
+ 	__u8  reserved15[0x2d0 - 0x24c];	/* 0x24c */
 	struct e820entry e820_map[E820MAX];	/* 0x2d0 */
 						/* 0x550 */
 } __attribute__((packed));
#8 lore raw

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

In reply to Eric W. Biederman

Please apply,

This patch revs the x86 boot protocol, making the bean counting information, and the 32bit entry point available, to bootloaders that need it.

Eric

Documentation/i386/boot.txt +240 -34
diff -uNr linux-2.5.12.boot.build/Documentation/i386/boot.txt linux-2.5.12.boot.proto/Documentation/i386/boot.txt
@@ -4,6 +4,9 @@
 		    H. Peter Anvin <[email protected]>
 			Last update 2002-01-01
 
+		Eric Biederman <[email protected]>
+		       Last update 28 April 2002
+
 On the i386 platform, the Linux kernel uses a rather complicated boot
 convention.  This has evolved partially due to historical aspects, as
 well as the desire in the early days to have the kernel itself be a
@@ -35,6 +38,14 @@
 		initrd address available to the bootloader.
 
 
+Protocol 2.04:  (Kernel 2.5.x) 
+		- Decompression in place (smaller load footpribnt)
+		  The overhead is now 72KB below 1MB && 8 bytes above 1MB
+		- 32bit entry point support
+		- Exported the load time memory usage.
+		- zImage now has a larger memory footprint than bzImage.
+		  should we just kill zImage?
+
 **** MEMORY LAYOUT
 
 The traditional memory map for the kernel loader, used for Image or
@@ -100,34 +111,42 @@
 
 The header looks like:
 
-Offset	Proto	Name		Meaning
+Offset  Proto  Name                  Meaning
 /Size
 
-01F1/1	ALL	setup_sects	The size of the setup in sectors
-01F2/2	ALL	root_flags	If set, the root is mounted readonly
-01F4/2	ALL	syssize		DO NOT USE - for bootsect.S use only
-01F6/2	ALL	swap_dev	DO NOT USE - obsolete
-01F8/2	ALL	ram_size	DO NOT USE - for bootsect.S use only
-01FA/2	ALL	vid_mode	Video mode control
-01FC/2	ALL	root_dev	Default root device number
-01FE/2	ALL	boot_flag	0xAA55 magic number
-0200/2	2.00+	jump		Jump instruction
-0202/4	2.00+	header		Magic signature "HdrS"
-0206/2	2.00+	version		Boot protocol version supported
-0208/4	2.00+	realmode_swtch	Boot loader hook (see below)
-020C/2	2.00+	start_sys	The load-low segment (0x1000) (obsolete)
-020E/2	2.00+	kernel_version	Pointer to kernel version string
-0210/1	2.00+	type_of_loader	Boot loader identifier
-0211/1	2.00+	loadflags	Boot protocol option flags
-0212/2	2.00+	setup_move_size	Move to high memory size (used with hooks)
-0214/4	2.00+	code32_start	Boot loader hook (see below)
-0218/4	2.00+	ramdisk_image	initrd load address (set by boot loader)
-021C/4	2.00+	ramdisk_size	initrd size (set by boot loader)
-0220/4	2.00+	bootsect_kludge	DO NOT USE - for bootsect.S use only
-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
+01F1/1  ALL    setup_sects           The size of the setup in sectors
+01F2/2  ALL    root_flags            If set, the root is mounted readonly
+01F4/2  ALL    syssize               DO NOT USE - for bootsect.S use only
+01F6/2  ALL    swap_dev              DO NOT USE - obsolete
+01F8/2  ALL    ram_size              DO NOT USE - for bootsect.S use only
+01FA/2  ALL    vid_mode              Video mode control
+01FC/2  ALL    root_dev              Default root device number
+01FE/2  ALL    boot_flag             0xAA55 magic number
+0200/2  2.00+  jump                  Jump instruction
+0202/4  2.00+  header_magic          Magic signature "HdrS"
+0206/2  2.00+  protocol_version      Boot protocol version supported
+0208/4  2.00+  realmode_swtch        Boot loader hook (see below)
+020C/2  2.00+  start_sys_seg         Segment the zImage kernel was loaded at (0x1000) (obsolete)
+020E/2  2.00+  kernel_version        Pointer to kernel version string
+0210/1  2.00+  type_of_loader        Boot loader identifier
+0211/1  2.00+  loadflags             Boot protocol option flags
+0212/2  2.00+  setup_move_size       Move to high memory size (used with hooks)
+0214/4  2.00+  code32_start          Boot loader hook (see below)
+0218/4  2.00+  initrd_start          initrd load address (set by boot loader)
+021C/4  2.00+  initrd_size           initrd size (set by boot loader)
+0220/4  2.00+  bootsect_kludge       DO NOT USE - for bootsect.S use only
+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+  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+  real_base             Default load address of real mode code
+0238/4  2.04+  real_memsz            Memory used @ real_base
+023C/4  2.04+  real_filesz           Amount of data loaded @ real_base
+0240/4  2.04+  kern_base             Kernel decompressor load address
+0244/4  2.04+  kern_memsz            Memory used @ kern_base
+0248/4  2.04+  kern_filesz           Amount of data loaeded @ kern_base
 
 For backwards compatibility, if the setup_sects field contains 0, the
 real value is 4.
@@ -180,8 +199,14 @@
   loadflags, heap_end_ptr:
 	If the protocol version is 2.01 or higher, enter the
 	offset limit of the setup heap into heap_end_ptr and set the
-	0x80 bit (CAN_USE_HEAP) of loadflags.  heap_end_ptr appears to
-	be relative to the start of setup (offset 0x0200).
+	0x80 bit (CAN_USE_HEAP) of loadflags.  heap_end_ptr is
+	relative to the start of setup (offset 0x0200).
+
+	If the protocol version is 2.04 or higher set the 0x40 bit
+	(STAY_PUT).  This explictly tells the real mode code that you
+	don't expect it to relocate itself to 0x90000.  No earlier
+	protocols versions look at this bit so it is safe to set it
+	unconditionally.
 
   setup_move_size: 
 	When using protocol 2.00 or 2.01, if the real mode
@@ -190,17 +215,20 @@
 	additional data (such as the kernel command line) moved in
 	addition to the real-mode kernel itself.
 
-  ramdisk_image, ramdisk_size:
+  initrd_start, initrd_size:
 	If your boot loader has loaded an initial ramdisk (initrd),
-	set ramdisk_image to the 32-bit pointer to the ramdisk data
-	and the ramdisk_size to the size of the ramdisk data.
+	set initrd_start to the 32-bit pointer to the ramdisk data
+	and the initrd_size to the size of the ramdisk data.
 
 	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.
 
+	With boot protocol 2.04 and above the initrd can be loaded
+	as low as kern_base + kern_memsz.
+
   cmd_line_ptr:
 	If the protocol version is 2.02 or higher, this is a 32-bit
 	pointer to the kernel command line.  The kernel command line
@@ -248,6 +276,11 @@
 	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
 
@@ -269,8 +302,8 @@
 	if ( protocol >= 0x0200 ) {
 		type_of_loader = <type code>;
 		if ( loading_initrd ) {
-			ramdisk_image = <initrd_address>;
-			ramdisk_size = <initrd_size>;
+			initrd_start = <initrd_address>;
+			initrd_size = <initrd_size>;
 		}
 		if ( protocol >= 0x0201 ) {
 			heap_end_ptr = 0x9000 - 0x200;
@@ -436,3 +469,176 @@
 
 	After completing your hook, you should jump to the address
 	that was in this field before your boot loader overwrote it.
+
+
+**** THE COMPRESSED KERNEL HEADER
+
+As of boot protocol version 2.04 a header has been added to the
+compressed data, to reduce information loss.  Most bootloaders
+should never need to look at these fields.
+
+Offset  Proto  Name             Meaning
+/Size
+
+0000/4  2.04+  jump             Jump Instruction
+0004/4  2.04+  input_addr       Load address of compressed data
+0008/4  2.04+  input_len        Length of compressed data
+000C/4  2.04+  output_overhang  Extra bytes needed for inplace decompression
+0010/4  2.04+  kernel_base      Kernel load address
+0014/4  2.04+  kernel_filesz    Memory usage @ kernel_base     
+0018/4  2.04+  kernel_memsz     Data size @ kernel_base
+001C/4  2.04+  unzip_filesz     Decompressor code/data size
+0020/4  2.04+  unzip_memsz      Decompressor code memory usage
+
+**** DETAILED DESCRIPTION OF FIELDS
+
+  entry32_off:
+	The unsigned 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.
+
+	The 32bit entry point is a mechanism for entering the kernel
+	without doing 16bit PC BIOS calls.  Very useful for systems
+	with alternative firmware implementations.
+
+	A bootloader using the 32bit entry point should verify that
+	there are real_memsz bytes available at real_base (real_base
+	remains relocatable in bzImages).  And that there kern_memsz
+	bytes available at kern_base.  For zImages you should also
+	verify that there are kernel_memsz bytes available at
+	kernel_base.
+
+	Verifing there is enough memory for the kernel to load is
+	necessary for using the 32bit entry point, and suggested for
+	the 16bit entry point.  In the case of the 32bit entry point
+	the kernel has no ability to talk to whatever weird firmware you
+	have until it is fully loaded.
+
+	The 32bit entry point makes the following assumptions.  You
+	are calling it protected mode.  Paging is disabled.  All
+	segment registers are loaded with a 32bit segment with a base
+	of 0, and a limit of 0xFFFFFFFF (limitless).  Either %esp == 0
+	and you are using the default real_base or %esp points to a
+	stack large enough to hold at least 12 new bytes of data.
+
+
+  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.
+
+  input_addr/input_len:
+	The kernel is loaded into memory in compressed form.
+	input_addr is the location where the compressed data is
+	loaded, and input_len is the count of how many bytes of
+	compressed data there are.
+	
+	These two variables allow an external program to inspect a
+	bzImage and find the compressed data.  This is mostly of use
+	to build.c as it computes output_overhang but other programs
+	may find it useful as well.
+
+  output_overhang:
+	Most decompression algorithms may transformed into near
+	in-place algorithms by simply overlapping the compressed data
+	and the decompressed data buffers.  For a particular
+	decompression algorithm then the question becomes how much
+	overlap is safe.  More practically how much must the
+	compressed data stick out from the end of the decompressed
+	data buffer for this technique to work.
+
+	output_overhang is that amount the compressed data buffer
+	must extend beyond the decompressed data buffer for
+	decompression in place to work for the linux kernel.
+
+	build.c is responsible for computing this number.  For
+	gzip typically this number is 8 (file length and checksum).
+	But in pathological cases it may be worse.
+
+  real_base, real_memsz, real_filesz, 
+  kern_base, kern_memsz, kern_filesz,
+  kernel_base, kernel_memsz, kernel_filesz,
+  unzip_memsz, unzip_filesz,
+
+	Up to this point building a zImage or a bzImage has been a
+	very lossy process.  The introduction of these 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.
+
+	Program segments are described with 3 variables.  The base
+	address where the segment is loaded in memory.  The file size
+	which records the amount of data in the input file that is
+	loaded into memory.  The memory size which is greater than or
+	equal to the file size and records how much memory this
+	program segment consumes.
+
+	base   +-----------+
+	       | code/data |
+	filesz +-----------+
+	       |  bss      |
+	memsz  +-----------+
+
+	The real program segment (real_base, real_filesz, real_memsz)
+	describes the memory usage of the real mode code from 4KB to
+	640KB.  The real code segment and the command line must be  
+	located somewhere in this range.
+
+	The compressed kernel segment (kern_base, kern_filesz,
+	kern_memsz) describes the memory usage of the compressed
+	kernel.  For a zImage this is memory below 1MB for a bzImage
+	this is memory starting at 1MB.
+
+	For bzImages it is sufficient to look at the real program
+	segment, and the compressed kernel segment to get the entire
+	boottime memory usage of the kernel.  real_memsz is increased
+	to also document the decompressors real memory usage, and the
+	kern_memsz value is increased to document the decompressed
+	kernels memory usage.
+
+	You can look at heap_end_ptr to get the actual memory
+	footprint of the real mode segment.  Just the decompressors
+	memory footprint is kern_base + kernel_filesz +
+	output_overhang, if unzip_memsz bytes are available of real
+	memory, and kern_base + kernel_filesz + output_overhang +
+	unzip_memsz bytes otherwise.
+	
+	The decompressed kernel segment (kernel_base, kernel_filesz,
+	kernel_memsz) describes the memory usage of the decompresed
+	kernel (essentially vmlinux). 
+
+	The decompressor segment (load_address, unzip_filesz, unzip_memsz)
+	describes the memory usage of the kernel decompressor,
+	not counting the compressed data.
+
+	The real program segment describes memory in the range
+	4KB (0x1000) to 640KB (0xa0000) that the real mode kernel
+	uses.  real_base may be moved lower or higher in memory if
+	there is a memory conflict with another address.  When doing
+	so the following considerations should apply.
+
+		For a zImage the range [real_base, real_base +
+		real_memsz) should not overlap the range [ kern_base,
+		kern_base + kern_memsz].
+
+		Ensure that the range [real_base, real_base +
+		real_memsz) is within the range [ 0x1000, 0xa0000).
+		
+	With this information it becomes safe to statically relocate
+	the real mode kernel as well as to dynamically relocate the
+	real_mode kernel.
arch/i386/Config.help +6 -0
diff -uNr linux-2.5.12.boot.build/arch/i386/Config.help linux-2.5.12.boot.proto/arch/i386/Config.help
@@ -803,6 +803,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_X86_MCE
   Machine Check Exception support allows the processor to notify the
   kernel if it detects a problem (e.g. overheating, component failure).
arch/i386/boot/realmode.lds +1 -1
diff -uNr linux-2.5.12.boot.build/arch/i386/boot/realmode.lds linux-2.5.12.boot.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 +190 -21

291 lines not on this page · raw message

arch/i386/config.in +1 -0
diff -uNr linux-2.5.12.boot.build/arch/i386/config.in linux-2.5.12.boot.proto/arch/i386/config.in
@@ -282,6 +282,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 +74 -17

143 lines not on this page · raw message

include/asm-i386/boot_param.h +8 -3
diff -uNr linux-2.5.12.boot.build/include/asm-i386/boot_param.h linux-2.5.12.boot.proto/include/asm-i386/boot_param.h
@@ -83,15 +83,20 @@
 	__u32 cmd_line_ptr;			/* 0x228 */
 	/* 2.03+ */
 	__u32 ramdisk_max;			/* 0x22c */
-	/* Below this point for internal kernel use only */
-	__u32 pad2;				/* 0x230 */
+	/* 2.04+ */
+	__u16 entry32_off;			/* 0x230 */
+	__u16 internal_cmdline_off;		/* 0x232 */
 	__u32 real_base;			/* 0x234 */
 	__u32 real_memsz;			/* 0x238 */
 	__u32 real_filesz;			/* 0x23c */
  	__u32 kern_base;			/* 0x240 */
  	__u32 kern_memsz;			/* 0x244 */
  	__u32 kern_filesz;			/* 0x248 */
- 	__u8  reserved15[0x2d0 - 0x24c];	/* 0x24c */
+	/* Below this point for internal kernel use only */
+	__u32 entry32_used;			/* 0x24c */
+	__u32 entry32_16_off;			/* 0x250 */
+	struct initial_regs32 regs;		/* 0x254 */
+	__u8  reserved15[0x2d0 - 0x274];	/* 0x274 */
 	struct e820entry e820_map[E820MAX];	/* 0x2d0 */
 						/* 0x550 */
 } __attribute__((packed));
#9 lore raw

PATCH 1/1 x86 Boot enhancements, LinuxBIOS support 10/11

In reply to Eric W. Biederman

Please apply,

This patch adds support for LinuxBIOS.

Eric

arch/i386/Config.help +16 -0
diff -uNr linux-2.5.12.boot.proto/arch/i386/Config.help linux-2.5.12.boot.linuxbios/arch/i386/Config.help
@@ -803,6 +803,22 @@
   a work-around for a number of buggy BIOSes. Switch this option on if
   your computer crashes instead of powering off properly.
 
+LinuxBIOS support
+CONFIG_LINUXBIOS
+  LinuxBIOS is an alternative GPL'd firmware initially for x86
+  compatible machines.  LinuxBIOS attempts to be a simple and as fast
+  as possible, and is initially optimized for linux.  The interface to
+  the OS is a table at the beginning of memory.  Which should make the
+  inevitable firmware bugs easier to work around, as should the source
+  code :)  A goal of this table is to provide enough information so
+  that any OS but especially linux does not need to have motherboard
+  specific knowledge.
+
+  This first release only provides LinuxBIOS detection (by detecting
+  it's table) and memory size detection. 
+
+  For more information on LinuxBIOS see http://www.linuxbios.org
+
 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.
arch/i386/config.in +1 -0
diff -uNr linux-2.5.12.boot.proto/arch/i386/config.in linux-2.5.12.boot.linuxbios/arch/i386/config.in
@@ -206,6 +206,7 @@
    fi
 fi
 
+bool 'LinuxBIOS support' CONFIG_LINUXBIOS
 endmenu
 
 mainmenu_option next_comment
arch/i386/defconfig +1 -0
diff -uNr linux-2.5.12.boot.proto/arch/i386/defconfig linux-2.5.12.boot.linuxbios/arch/i386/defconfig
@@ -119,6 +119,7 @@
 CONFIG_BINFMT_MISC=y
 CONFIG_PM=y
 # CONFIG_APM is not set
+# CONFIG_LINUXBIOS is not set
 
 #
 # Memory Technology Devices (MTD)
arch/i386/kernel/Makefile +1 -0
diff -uNr linux-2.5.12.boot.proto/arch/i386/kernel/Makefile linux-2.5.12.boot.linuxbios/arch/i386/kernel/Makefile
@@ -42,6 +42,7 @@
 obj-$(CONFIG_SMP)		+= smp.o smpboot.o trampoline.o
 obj-$(CONFIG_X86_LOCAL_APIC)	+= mpparse.o apic.o nmi.o
 obj-$(CONFIG_X86_IO_APIC)	+= io_apic.o
+obj-$(CONFIG_LINUXBIOS)		+= linuxbios.o
 ifdef CONFIG_VISWS
 obj-y += setup-visws.o
 obj-$(CONFIG_X86_VISWS_APIC)	+= visws_apic.o
arch/i386/kernel/linuxbios.c +103 -0

103 lines not on this page · raw message

arch/i386/kernel/linuxbios_tables.h +82 -0

82 lines not on this page · raw message

arch/i386/kernel/setup.c +6 -2
diff -uNr linux-2.5.12.boot.proto/arch/i386/kernel/setup.c linux-2.5.12.boot.linuxbios/arch/i386/kernel/setup.c
@@ -119,6 +119,7 @@
 #include <asm/mmu_context.h>
 #include <asm/boot.h>
 #include <asm/boot_param.h>
+#include <asm/linuxbios.h>
 
 /*
  * Machine setup..
@@ -265,7 +266,7 @@
 	}
 }
 
-static void __init add_memory_region(unsigned long long start,
+void __init add_memory_region(unsigned long long start,
                                   unsigned long long size, int type)
 {
 	int x = e820.nr_map;
@@ -283,7 +284,7 @@
 
 #define E820_DEBUG	1
 
-static void __init print_memory_map(char *who)
+void __init print_memory_map(char *who)
 {
 	int i;
 
@@ -775,6 +776,9 @@
 	if (entry16) {
 		read_entry16_params(params);
 	}
+
+	/* Attempt to get the LinuxBIOS parameters */
+	read_linuxbios_params();
 
 	/* Read user specified params */
 	parse_mem_cmdline(cmdline_p);
include/asm-i386/e820.h +3 -0
diff -uNr linux-2.5.12.boot.proto/include/asm-i386/e820.h linux-2.5.12.boot.linuxbios/include/asm-i386/e820.h
@@ -36,6 +36,9 @@
 };
 
 extern struct e820map e820;
+extern void  add_memory_region(unsigned long long start,
+	unsigned long long size, int type);
+extern void print_memory_map(char *who);
 #endif/*!__ASSEMBLY__*/
 
 #endif/*__E820_HEADER*/
include/asm-i386/linuxbios.h +10 -0
diff -uNr linux-2.5.12.boot.proto/include/asm-i386/linuxbios.h linux-2.5.12.boot.linuxbios/include/asm-i386/linuxbios.h
@@ -0,0 +1,10 @@
+#ifndef __ASMi386_LINUXBIOS_H
+#define __ASMi386_LINUXBIOS_H
+
+#ifdef CONFIG_LINUXBIOS
+void read_linuxbios_params(void);
+#else
+#define read_linuxbios_params()
+#endif /* CONFIG_LINUXBIOS */
+
+#endif
#10 lore raw

PATCH 1/1 x86 Boot enhancements, bzElf support 11/11

In reply to Eric W. Biederman

Please apply,

This patch allows a bzELF image to be built instead of a bzImage. A bzELF is just a bzImage represented in the ELF file format. The transform from bzELF to bzImage is 1-1.

Eric

arch/i386/Makefile +3 -0
diff -uNr linux-2.5.12.boot.linuxbios/arch/i386/Makefile linux-2.5.12.boot.elf/arch/i386/Makefile
@@ -119,6 +119,9 @@
 bzImage: vmlinux
 	@$(MAKEBOOT) bzImage
 
+bzElf: vmlinux
+	@$(MAKEBOOT) bzElf
+
 compressed: zImage
 
 zlilo: vmlinux
arch/i386/boot/Makefile +4 -1
diff -uNr linux-2.5.12.boot.linuxbios/arch/i386/boot/Makefile linux-2.5.12.boot.elf/arch/i386/boot/Makefile
@@ -18,6 +18,9 @@
 bzImage: $(CONFIGURE) tools/build $(TOPDIR)/vmlinux brealmode compressed/bvmlinux 
 	tools/build -b $(TOPDIR)/vmlinux brealmode compressed/bvmlinux bzImage
 
+bzElf: $(CONFIGURE) tools/build $(TOPDIR)/vmlinux brealmode compressed/bvmlinux 
+	tools/build -e -b $(TOPDIR)/vmlinux brealmode compressed/bvmlinux bzElf
+
 compressed/vmlinux: $(TOPDIR)/vmlinux
 	@$(MAKE) -C compressed vmlinux
 
@@ -75,5 +78,5 @@
 clean:
 	rm -f tools/build
 	rm -f realmode zImage
-	rm -f brealmode bzImage
+	rm -f brealmode bzImage bzElf
 	@$(MAKE) -C compressed clean
arch/i386/boot/tools/build.c +231 -7

297 lines not on this page · raw message

#11 lore raw

Re: [PATCH 2.5.12] x86 Boot enhancements, boot protocol 2.04 9/11

In reply to Eric W. Biederman
Followup to:  <[email protected]>
By author:    [email protected] (Eric W. Biederman)
In newsgroup: linux.dev.kernel
Quoted 1 line

+0200/2 2.00+ jump Jump instruction

I would like to make it an explicit part of the protocol that the jump instruction must jump to the first byte following the header. It can therefore be used to determine the end of the header.

-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]>
#12 lore raw

Re: [PATCH 2.5.12] x86 Boot enhancements, boot protocol 2.04 9/11

In reply to Eric W. Biederman
Followup to:  <[email protected]>
By author:    [email protected] (Eric W. Biederman)
In newsgroup: linux.dev.kernel
Quoted 8 lines

For backwards compatibility, if the setup_sects field contains 0, the real value is 4.

(quoted diff) +0 -1
@@ -180,8 +199,14 @@
   loadflags, heap_end_ptr:
 	If the protocol version is 2.01 or higher, enter the
 	offset limit of the setup heap into heap_end_ptr and set the
-	0x80 bit (CAN_USE_HEAP) of loadflags.  heap_end_ptr appears to

Review line 210

Quoted 10 lines
(quoted diff) +8 -1
-	be relative to the start of setup (offset 0x0200).
+	0x80 bit (CAN_USE_HEAP) of loadflags.  heap_end_ptr is
+	relative to the start of setup (offset 0x0200).
+
+	If the protocol version is 2.04 or higher set the 0x40 bit
+	(STAY_PUT).  This explictly tells the real mode code that you
+	don't expect it to relocate itself to 0x90000.  No earlier
+	protocols versions look at this bit so it is safe to set it
+	unconditionally.
 

Hang on here... this is bullsh*t. The real-mode code should not be relocated if the cmd_line_ptr field is set. If you don't want to pass a command line, set cmd_line_ptr to an empty string "". There should be no need for an additional protocol here; in fact, having two protocols only means the boot loader has to do both, in effect, so what's the point?!?

Review line 212

Quoted 2 lines
(quoted diff) +2 -0
+	With boot protocol 2.04 and above the initrd can be loaded
+	as low as kern_base + kern_memsz.

It's still a bad idea, for several reasons:

a) Adds to the number of configurations that have to be tested, for absolutely no good reason.

b) It may be OK for the Linux kernel proper, but it is *NOT* acceptable for some other programs that use the Linux boot protocol.

-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]>
#13 lore raw

Re: [PATCH 2.5.12] x86 Boot enhancements, bzElf support 11/11

In reply to Eric W. Biederman
Followup to:  <[email protected]>
By author:    [email protected] (Eric W. Biederman)
In newsgroup: linux.dev.kernel
Quoted 7 lines

Please apply,

This patch allows a bzELF image to be built instead of a bzImage. A bzELF is just a bzImage represented in the ELF file format. The transform from bzELF to bzImage is 1-1.

... thus adding another binary format for no gain.

-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]>
#14 lore raw
In reply to Eric W. Biederman

Hi!

Quoted 5 lines

#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

Signature · 2 lines
Philips Velo 1: 1"x4"x8", 300gram, 60, 12MB, 40bogomips, linux, mutt,
details at http://atrey.karlin.mff.cuni.cz/~pavel/velo/index.html.
#15 lore raw
In reply to Eric W. Biederman
Quoted 10 lines · Pavel Machek

Hi!

Quoted 5 lines

#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

#16 lore raw
In reply to Eric W. Biederman

Hi!

Quoted 11 lines
Quoted 8 lines
Quoted 5 lines

#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?

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

Signature · 2 lines
Casualities in World Trade Center: ~3k dead inside the building,
cryptography in U.S.A. and free speech in Czech Republic.
#17 lore raw
In reply to Eric W. Biederman
Quoted 8 lines · Pavel Machek

Hi!

Quoted 6 lines
Quoted 6 lines
Quoted 5 lines

#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.

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

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.

Quoted 2 lines

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

#18 lore raw

Re: [PATCH 2.5.12] x86 Boot enhancements, 32bit entries 6/11

In reply to Eric W. Biederman

Hi!

Quoted 5 lines

This patch cleans up the 32bit kernel entry points so they don't assume who their caller is, making them usable by other than setup.S

For arch/i386/kernel/head.S this untangles the secondary cpu and the bootstrap entry points making the code more readable.

Hmm, but making variables called eax, ebx, ... is surely going to confuse someone. What about bootup_eax, .. ?

Quoted 6 lines
(quoted diff) +6 -0
+	/*
+	 * Save the initial registers
+	 */
+	movl %eax, eax
+	movl %ebx, ebx
+	movl %ecx, ecx

Review

Quoted 10 lines
(quoted diff) +10 -0
+	movl %edx, edx
+	movl %esi, esi
+	movl %edi, edi
+	movl %esp, esp
+	movl %ebp, ebp
+
+	/*
+	 * Setup the stack
+	 */
+	movl stack_start, %esp

Pavel

Signature · 2 lines
Philips Velo 1: 1"x4"x8", 300gram, 60, 12MB, 40bogomips, linux, mutt,
details at http://atrey.karlin.mff.cuni.cz/~pavel/velo/index.html.
#19 lore raw
In reply to Eric W. Biederman

Hi!

Quoted 11 lines
Quoted 5 lines
Quoted 2 lines

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.

Quoted 2 lines

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

Quoted 6 lines

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?

Switch to kernel-controlled-console with messages about suspend is how I'm handling this in S4 (suspend-to-disk).

Quoted 2 lines

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

Well, not neccessary since I can switch consoles back and forth in kernel just fine.
Pavel

Signature · 2 lines
Casualities in World Trade Center: ~3k dead inside the building,
cryptography in U.S.A. and free speech in Czech Republic.