Re: kernel loading question

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, 5 Dec 2005, linux-os (Dick Johnson) wrote:

>
> On Sat, 3 Dec 2005, Daniel Bonekeeper wrote:
>
>> Well, this probably should not be posted here, but who knows ? =)
>>
>> Well, on arch/i386/boot/compressed/head.S line 65 we call
>> decompress_kernel that decompresses the kernel starting at $0x100000.
>> If we were loaded high, we first move the code back to $0x1000 before
>> ljmp'ing it.
>>
>> My question is: why, when loaded high, we care to disable interrupts
>> (cli  # make sure we don't get interrupted) while otherwise, we don't
>> do that ? in both cases, aren't we supposed to disable cli (as they
>> can happen in both situations) ?
>>
>> Since currently, the kernel boots fine for everybody in the world, I
>> know that this is not a bug... but why don't disable interruptions on
>> both cases ?
>>
>> Thanks !
>
> The first thing to do when looking at assembly language files
> is to find what symbols are global (.globl or .global). Unlike
> 'C' the stuff doesn't default to being visible from other
> files. Given that, you will see that code executes from
> startup_32, the only way "in" since it's the only global
> symbol. The second instruction is 'cli', which will disable
> interrupts on the current processor.
>
> Now, later on in the code is the sequence:
> 		pushl	$0
> 		popfl
>
> ... which will further clear any flags so the interrupt-enable
> flag is truly disabled there, also. Later on, there are redundant
> 'cld' instructions as well as an additional 'cli' instruction.
>
> These probably occurred because the code was assembled from
> various pieces and nobody bothered to review it for such
> redundancy.
>
> Getting rid of the extra instructions will save 3 or 4 bytes
> of code. Since this code executes only once, it's certainly
> not in the "fast-path" so nobody has bothered to clean it.
> If you would like to clean up the code and submit a patch
> it probably would be accepted.
>
> I will test any patch you may want to produce.
>
> Cheers,
> Dick Johnson
> Penguin : Linux version 2.6.13.4 on an i686 machine (5589.44 BogoMips).
> Warning : 98.36% of all statistics are fiction.


Here is a patch that works both on the normal Pentium and the
ELAN which is a '486'. It hasn't been tested on __everything__
because I don't have a '386. Nevertheless, it should work
everywhere and it contains a few cleanups as well. Just in
case the mailer screws it up, it is attached as a plain
text file as well.

Signed Off By:  Richard B. Johnson	[email protected]

--------

--- linux-2.6.13.4/arch/i386/boot/compressed/head.S.orig	2005-12-05 09:23:22.000000000 -0500
+++ linux-2.6.13.4/arch/i386/boot/compressed/head.S	2005-12-05 10:39:56.000000000 -0500
@@ -18,9 +18,21 @@
   * mode.
   */

-/*
- * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
- */
+#
+#  High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
+#
+#  Dec 5, 2005	[email protected]
+#  Removed most of the old-style 'C' comment format and replaced with
+#  GAS comment delimiters.
+#
+#  Dec 5, 2005	[email protected]
+#  Removed many redundant flag operations. Adjusted offset of
+#  the move_routine_start to a 16-byte boundary so it is truly
+#  position-independent.
+#
+#  Dec 5, 2005	[email protected]
+#  Fixed A20 detection code.
+#
  .text

  #include <linux/linkage.h>
@@ -30,41 +42,38 @@
  	.globl startup_32

  startup_32:
-	cld
  	cli
-	movl $(__BOOT_DS),%eax
-	movl %eax,%ds
+	movl $(__BOOT_DS),%eax	# Linear address-space
+	movl %eax,%ds		# Set segments
  	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
-
-/*
- * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
- * confuse the debugger if this code is traced.
- * XXX - best to initialize before switching to protected mode.
- */
-	pushl $0
-	popfl
-/*
- * Clear BSS
- */
+	lss stack_start,%esp	# Set stack
+	xorl %eax,%eax		# Clear
+	pushl %eax
+	popfl			# Clear all flags
+#
+#	Check for at least 20-bit addressing, (A20 is enabled).
+#
+	movl	$__PHYSICAL_START, %ebx
+	movl	(%ebx), %eax		# Save whatever is there
+	movl	$0xfeedface, (%ebx)	# Set magic
+1:	cmpl	$0xfeedface, (%ebx)	# See if 32-bits
+	jnz	1b			# Hang forever if not
+	movl	%eax, (%ebx)		# Put the code back
+#
+#	Clear BSS
+#
  	xorl %eax,%eax
  	movl $_edata,%edi
  	movl $_end,%ecx
  	subl %edi,%ecx
-	cld
  	rep
  	stosb
-/*
- * Do the decompression, and jump to the new kernel..
- */
+#
+#	Do the decompression, and jump to the new kernel..
+#
  	subl $16,%esp	# place for structure on the stack
  	movl %esp,%eax
  	pushl %esi	# real mode pointer as second arg
@@ -77,20 +86,18 @@
  	xorl %ebx,%ebx
  	ljmp $(__BOOT_CS), $__PHYSICAL_START

-/*
- * We come here, if we were loaded high.
- * We need to move the move-in-place routine down to 0x1000
- * and then start it with the buffer addresses in registers,
- * which we got from the stack.
- */
-3:
-	movl $move_routine_start,%esi
+#
+#	We come here, if we were loaded high.
+#	We need to move the move-in-place routine down to 0x1000
+#	and then start it with the buffer addresses in registers
+#	which we got from the stack.
+#
+3:	movl $move_routine_start,%esi
  	movl $0x1000,%edi
  	movl $move_routine_end,%ecx
  	subl %esi,%ecx
  	addl $3,%ecx
  	shrl $2,%ecx
-	cld
  	rep
  	movsl

@@ -101,13 +108,13 @@
  	popl %edx	# high_buffer_start
  	popl %eax	# hcount
  	movl $__PHYSICAL_START,%edi
-	cli		# make sure we don't get interrupted
  	ljmp $(__BOOT_CS), $0x1000 # and jump to the move routine

-/*
- * Routine (template) for moving the decompressed kernel in place,
- * if we were high loaded. This _must_ PIC-code !
- */
+#
+#	Routine (template) for moving the decompressed kernel in place,
+#	when we are high loaded. This _must_ be position-independent code!
+#
+.align	0x10
  move_routine_start:
  	movl %ecx,%ebp
  	shrl $2,%ecx

-----------



Cheers,
Dick Johnson
Penguin : Linux version 2.6.13.4 on an i686 machine (5589.44 BogoMips).
Warning : 98.36% of all statistics are fiction.
.


****************************************************************
The information transmitted in this message is confidential and may be privileged.  Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited.  If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to [email protected] - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.
--- linux-2.6.13.4/arch/i386/boot/compressed/head.S.orig	2005-12-05 09:23:22.000000000 -0500
+++ linux-2.6.13.4/arch/i386/boot/compressed/head.S	2005-12-05 10:39:56.000000000 -0500
@@ -18,9 +18,21 @@
  * mode.
  */
 
-/*
- * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
- */
+#
+#  High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
+#
+#  Dec 5, 2005	[email protected]
+#  Removed most of the old-style 'C' comment format and replaced with
+#  GAS comment delimiters.
+#
+#  Dec 5, 2005	[email protected]
+#  Removed many redundant flag operations. Adjusted offset of
+#  the move_routine_start to a 16-byte boundary so it is truly
+#  position-independent.
+#
+#  Dec 5, 2005	[email protected]
+#  Fixed A20 detection code.
+#
 .text
 
 #include <linux/linkage.h>
@@ -30,41 +42,38 @@
 	.globl startup_32
 	
 startup_32:
-	cld
 	cli
-	movl $(__BOOT_DS),%eax
-	movl %eax,%ds
+	movl $(__BOOT_DS),%eax	# Linear address-space
+	movl %eax,%ds		# Set segments
 	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
-
-/*
- * Initialize eflags.  Some BIOS's leave bits like NT set.  This would
- * confuse the debugger if this code is traced.
- * XXX - best to initialize before switching to protected mode.
- */
-	pushl $0
-	popfl
-/*
- * Clear BSS
- */
+	lss stack_start,%esp	# Set stack
+	xorl %eax,%eax		# Clear
+	pushl %eax
+	popfl			# Clear all flags
+#
+#	Check for at least 20-bit addressing, (A20 is enabled).
+#
+	movl	$__PHYSICAL_START, %ebx
+	movl	(%ebx), %eax		# Save whatever is there
+	movl	$0xfeedface, (%ebx)	# Set magic
+1:	cmpl	$0xfeedface, (%ebx)	# See if 32-bits
+	jnz	1b			# Hang forever if not
+	movl	%eax, (%ebx)		# Put the code back
+#
+#	Clear BSS
+#
 	xorl %eax,%eax
 	movl $_edata,%edi
 	movl $_end,%ecx
 	subl %edi,%ecx
-	cld
 	rep
 	stosb
-/*
- * Do the decompression, and jump to the new kernel..
- */
+#
+#	Do the decompression, and jump to the new kernel..
+#
 	subl $16,%esp	# place for structure on the stack
 	movl %esp,%eax
 	pushl %esi	# real mode pointer as second arg
@@ -77,20 +86,18 @@
 	xorl %ebx,%ebx
 	ljmp $(__BOOT_CS), $__PHYSICAL_START
 
-/*
- * We come here, if we were loaded high.
- * We need to move the move-in-place routine down to 0x1000
- * and then start it with the buffer addresses in registers,
- * which we got from the stack.
- */
-3:
-	movl $move_routine_start,%esi
+#
+#	We come here, if we were loaded high.
+#	We need to move the move-in-place routine down to 0x1000
+#	and then start it with the buffer addresses in registers
+#	which we got from the stack.
+#
+3:	movl $move_routine_start,%esi
 	movl $0x1000,%edi
 	movl $move_routine_end,%ecx
 	subl %esi,%ecx
 	addl $3,%ecx
 	shrl $2,%ecx
-	cld
 	rep
 	movsl
 
@@ -101,13 +108,13 @@
 	popl %edx	# high_buffer_start
 	popl %eax	# hcount
 	movl $__PHYSICAL_START,%edi
-	cli		# make sure we don't get interrupted
 	ljmp $(__BOOT_CS), $0x1000 # and jump to the move routine
 
-/*
- * Routine (template) for moving the decompressed kernel in place,
- * if we were high loaded. This _must_ PIC-code !
- */
+#
+#	Routine (template) for moving the decompressed kernel in place,
+#	when we are high loaded. This _must_ be position-independent code!
+#
+.align	0x10
 move_routine_start:
 	movl %ecx,%ebp
 	shrl $2,%ecx

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux