x86 Boot enhancements, boot params 1/11
Subsystems (2)
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
@@ -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
PATCH 1/1 x86 Boot enhancements, linker fixes 2/11
arch/i386/Makefile +1 -1
@@ -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
@@ -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
@@ -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/ : {
PATCH 1/1 x86 Boot enhancements, bzImage/zImage code differentiation 3/11
In reply to Eric W. BiedermanPlease apply
Differentiate the code that is needed in setup.S for zImage and bzImages.
Eric
arch/i386/boot/setup.S +14 -13
@@ -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
Re: [PATCH 2.5.12] x86 Boot enhancements, constants 4/11
In reply to Eric W. BiedermanPlease apply,
This patch introduces several constants to the x86 boot process.
Eric
arch/i386/boot/setup.S +8 -7
@@ -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
@@ -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
@@ -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
PATCH 1/1 x86 Boot enhancements, heap 5/11
In reply to Eric W. BiedermanPlease 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
@@ -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
@@ -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
@@ -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
@@ -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));
Re: [PATCH 2.5.12] x86 Boot enhancements, 32bit entries 6/11
In reply to Eric W. BiedermanPlease 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
PATCH 1/1 x86 Boot enhancements, footprint reduction 7/11
In reply to Eric W. BiedermanPlease 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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));
PATCH 1/1 x86 Boot enhancements, build beancounting 8/11
In reply to Eric W. BiedermanPlease 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
@@ -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
@@ -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
@@ -54,7 +54,7 @@ #endif .code16 -.text +.section ".bootsect", "ax", @progbits .global _start _start:
arch/i386/boot/realmode.lds +18 -0
@@ -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
@@ -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
@@ -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
@@ -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));
PATCH 1/1 x86 Boot enhancements, boot protocol 2.04 9/11
In reply to Eric W. BiedermanPlease 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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));
PATCH 1/1 x86 Boot enhancements, LinuxBIOS support 10/11
In reply to Eric W. BiedermanPlease apply,
This patch adds support for LinuxBIOS.
Eric
arch/i386/Config.help +16 -0
@@ -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
@@ -206,6 +206,7 @@ fi fi +bool 'LinuxBIOS support' CONFIG_LINUXBIOS endmenu mainmenu_option next_comment
arch/i386/defconfig +1 -0
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
PATCH 1/1 x86 Boot enhancements, bzElf support 11/11
In reply to Eric W. BiedermanPlease 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
@@ -119,6 +119,9 @@ bzImage: vmlinux @$(MAKEBOOT) bzImage +bzElf: vmlinux + @$(MAKEBOOT) bzElf + compressed: zImage zlilo: vmlinux
arch/i386/boot/Makefile +4 -1
@@ -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
Re: [PATCH 2.5.12] x86 Boot enhancements, boot protocol 2.04 9/11
In reply to Eric W. BiedermanFollowup 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]>
Re: [PATCH 2.5.12] x86 Boot enhancements, boot protocol 2.04 9/11
In reply to Eric W. BiedermanFollowup to: <[email protected]> By author: [email protected] (Eric W. Biederman) In newsgroup: linux.dev.kernel
Quoted 8 lines
For backwards compatibility, if the
setup_sectsfield 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]>
Re: [PATCH 2.5.12] x86 Boot enhancements, bzElf support 11/11
In reply to Eric W. BiedermanFollowup 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]>
Hi!
Quoted 5 lines
#5 boot.heap
============================================================
Modifyvideo.Sso thatmode_listis 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.
Quoted 10 lines · Pavel Machek
Hi!
Quoted 5 lines
#5 boot.heap
============================================================
Modifyvideo.Sso thatmode_listis 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
Hi!
Quoted 11 lines
Quoted 8 lines
Quoted 5 lines
#5 boot.heap
============================================================
Modifyvideo.Sso thatmode_listis 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.
Quoted 8 lines · Pavel Machek
Hi!
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
#5 boot.heap
============================================================
Modifyvideo.Sso thatmode_listis 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
Re: [PATCH 2.5.12] x86 Boot enhancements, 32bit entries 6/11
In reply to Eric W. BiedermanHi!
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.SFor
arch/i386/kernel/head.Sthis 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.
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.