Skip to contentSkip to conversation

x86 Boot enhancements, pic 16 4/9

PATCH In review Eric W. Biederman 4 participants 12 messages Apr 3, 2002 – Apr 5, 2002

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 x86 Boot enhancements, pic 16 4/9

Linus please apply,

This patch makes not changes to the generated object code.

Instead removes the assumption the code is linked to run at 0. The binary code is already PIC, this makes the build process the same way, making the build requirements more flexible.

Eric

arch/i386/boot/bootsect.S +16 -16
diff -uNr linux-2.5.7.boot2.32bit_entry/arch/i386/boot/bootsect.S linux-2.5.7.boot2.pic16/arch/i386/boot/bootsect.S
@@ -71,7 +71,7 @@
 	cld
 	rep
 	movsw
-	ljmp	$INITSEG, $go
+	ljmp	$INITSEG, $go - _start
 
 # bde - changed 0xff00 to 0x4000 to use debugger at 0x6400 up (bde).  We
 # wouldn't have to worry about this if we checked the top of memory.  Also
@@ -123,12 +123,12 @@
 # can be read, 15 if sector 15 can be read.  Otherwise guess 9.
 # Note that %cx = 0 from rep movsw above.
 
-	movw	$disksizes, %si		# table of sizes to try
+	movw	$disksizes - _start, %si	# table of sizes to try
 probe_loop:
 	lodsb
 	cbtw				# extend to word
-	movw	%ax, sectors
-	cmpw	$disksizes+4, %si
+	movw	%ax, sectors - _start
+	cmpw	$disksizes+4 - _start, %si
 	jae	got_sectors		# If all else fails, try 9
 
 	xchgw	%cx, %ax		# %cx = track and sector
@@ -146,7 +146,7 @@
 	movb	$0x07, %bl		# page 0, attribute 7 (normal)
 					# %bh is set above; int10 doesn't
 					# modify it
-	movw	$msg1, %bp
+	movw	$msg1 - _start, %bp
 	movw	$0x1301, %ax		# write string, move cursor
 	int	$0x10			# tell the user we're loading..
 
@@ -155,25 +155,25 @@
 # cylinder (for 9-sector 360K and 720K floppies).
 
 	movw	$0x0001, %ax		# set sread (sector-to-read) to 1 as
-	movw	$sread, %si		# the boot sector has already been read
+	movw	$sread - _start, %si	# the boot sector has already been read
 	movw	%ax, (%si)
 
 	call	kill_motor		# reset FDC
 	movw	$0x0200, %bx		# address = 512, in INITSEG
 next_step:
-	movb	setup_sects, %al
-	movw	sectors, %cx
+	movb	setup_sects - _start, %al
+	movw	sectors - _start, %cx
 	subw	(%si), %cx		# (%si) = sread
 	cmpb	%cl, %al
 	jbe	no_cyl_crossing
-	movw	sectors, %ax
+	movw	sectors - _start, %ax
 	subw	(%si), %ax		# (%si) = sread
 no_cyl_crossing:
 	call	read_track
 	pushw	%ax			# save it
 	call	set_next		# set %bx properly; it uses %ax,%cx,%dx
 	popw	%ax			# restore
-	subb	%al, setup_sects	# rest - for next step
+	subb	%al, setup_sects-_start	# rest - for next step
 	jnz	next_step
 
 	pushw	$SYSSEG
@@ -190,11 +190,11 @@
 # Segments are as follows: %cs = %ds = %ss = INITSEG,
 #	%es = SYSSEG, %fs = 0, %gs is unused.
 
-	movw	root_dev, %ax
+	movw	root_dev-_start, %ax
 	orw	%ax, %ax
 	jne	root_defined
 
-	movw	sectors, %bx
+	movw	sectors-_start, %bx
 	movw	$0x0208, %ax		# /dev/ps0 - 1.2Mb
 	cmpw	$15, %bx
 	je	root_defined
@@ -209,7 +209,7 @@
 
 	movb	$0, %al			# /dev/fd0 - autodetect
 root_defined:
-	movw	%ax, root_dev
+	movw	%ax, root_dev-_start
 
 # After that (everything loaded), we jump to the setup-routine
 # loaded directly after the bootblock:
@@ -242,13 +242,13 @@
 	shr	$4, %cx
 	add	%cx, %ax		# check offset
 #endif
-	cmpw	syssize, %ax		# have we loaded everything yet?
+	cmpw	syssize-_start, %ax	# have we loaded everything yet?
 	jbe	ok1_read
 
 	ret
 
 ok1_read:
-	movw	sectors, %ax
+	movw	sectors-_start, %ax
 	subw	(%si), %ax		# (%si) = sread
 	movw	%ax, %cx
 	shlw	$9, %cx
@@ -297,7 +297,7 @@
 set_next:
 	movw	%ax, %cx
 	addw	(%si), %ax		# (%si) = sread
-	cmp	sectors, %ax
+	cmp	sectors-_start, %ax
 	jne	ok3_set
 	movw	$0x0001, %ax
 	xorw	%ax, 2(%si)		# change head
arch/i386/boot/setup.S +50 -47

263 lines not on this page · raw message

arch/i386/boot/video.S +78 -78

457 lines not on this page · raw message

include/asm-i386/e820.h +1 -0
diff -uNr linux-2.5.7.boot2.32bit_entry/include/asm-i386/e820.h linux-2.5.7.boot2.pic16/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
#1 lore raw
Followup to:  <[email protected]>
By author:    [email protected] (Eric W. Biederman)
In newsgroup: linux.dev.kernel
Quoted 9 lines

Linus please apply,

This patch makes not changes to the generated object code.

Instead removes the assumption the code is linked to run at 0. The binary code is already PIC, this makes the build process the same way, making the build requirements more flexible.

Flexible in what way?

-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]>
#2 lore raw
In reply to Eric W. Biederman
Quoted 6 lines · H. Peter Anvin
Followup to:  <[email protected]>
By author:    [email protected] (Eric W. Biederman)
In newsgroup: linux.dev.kernel
Quoted 3 lines

Linus please apply,

Quoted 8 lines
Quoted 6 lines

This patch makes not changes to the generated object code.

Instead removes the assumption the code is linked to run at 0. The binary code is already PIC, this makes the build process the same way, making the build requirements more flexible.

Flexible in what way?

In that the object files generated can be treated as ordinary object files, instead of needing special treatment.

Since gas does not have an ASSUME segment directive to tell the assembler where base addresses point the current code is arguable broken. And this patch is a bug fix.

I don't really need this patch but it sure makes life easier.

Eric

#3 lore raw
In reply to Eric W. Biederman

Hello!

Quoted 3 lines

Instead removes the assumption the code is linked to run at 0. The binary code is already PIC, this makes the build process the same way, making the build requirements more flexible.

What are the reasons to do this change? The assumption that "linked at 0" assumptions looks pretty harmless and the "-start"'s everywhere are ugly.

Have a nice fortnight

Signature · 3 lines
Martin `MJ' Mares   <[email protected]>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
Lottery -- a tax on people who can't do math.
#4 lore raw
In reply to Eric W. Biederman
Quoted 8 lines · Martin Mares

Hello!

Quoted 3 lines

Instead removes the assumption the code is linked to run at 0. The binary code is already PIC, this makes the build process the same way, making the build requirements more flexible.

What are the reasons to do this change? The assumption that "linked at 0" assumptions looks pretty harmless and the "-start"'s everywhere are ugly.

Short answer the current assembly is broken.

Long answer.

Without the "-start"'s the gas generates a relocation record for every one of those instructions. The correct syntax with gas is ugly. If you can find the gas equivalent of an assume %ds ... directive I will use it.

The fact that you can't treat the generated .o as a normal object is simply a maintenance nightmare.

With this change it is possible to write a linker script that generates a bzImage. I won't do it as every other build of ld
is broken with respect to interesting linker scripts. But there are
still some subsets of that idea that make sense.

Eric

#5 lore raw
In reply to Eric W. Biederman

Hello!

Quoted 2 lines

The fact that you can't treat the generated .o as a normal object is simply a maintenance nightmare.

Why? You can easily convert it to a normal absolute .o file by objcopy.

Also, I think you could do the same in the linker script.

Have a nice fortnight

Signature · 3 lines
Martin `MJ' Mares   <[email protected]>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
Diplomacy is an art of saying "nice doggy" until you can find a rock.
#6 lore raw
In reply to Eric W. Biederman
Quoted 8 lines · Martin Mares

Hello!

Quoted 2 lines

The fact that you can't treat the generated .o as a normal object is simply a maintenance nightmare.

Why? You can easily convert it to a normal absolute .o file by objcopy.

Also, I think you could do the same in the linker script.

Show me a linker script that can link together bootsect.o and bsetup.o.

Eric

#7 lore raw
In reply to Eric W. Biederman

Hello!

Quoted 1 line

Show me a linker script that can link together bootsect.o and bsetup.o.

I don't have enough time to experiment with it at this very moment and I admit that the linker bugs you've mentioned make it impossible, but the objdump solution I mentioned (and tried a couple of minutes ago) works and although it isn't perfect, it's lovely compared to the "-start" hack.

Have a nice fortnight

Signature · 3 lines
Martin `MJ' Mares   <[email protected]>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
hAS ANYONE SEEN MY cAPSLOCK KEY?
#8 lore raw
In reply to Eric W. Biederman
Quoted 9 lines · Martin Mares

Hello!

Quoted 1 line

Show me a linker script that can link together bootsect.o and bsetup.o.

I don't have enough time to experiment with it at this very moment and I admit that the linker bugs you've mentioned make it impossible, but the objdump solution I mentioned (and tried a couple of minutes ago) works and although it isn't perfect, it's lovely compared to the "-start" hack.

Given that I want a relative offset, and I have explicitly coded a relative offset, I don't see how that is a hack. I see assembly for is telling the machine explicitly what to do and that does.

The fact the correct way to code the instruction looks ugly is a gas bug/deficiency. Perhaps a gas developer will look at how ugly that code is and improve gas.

One of the other reasons I want to do it this way is in case is to make copying code easier. If you use idioms that work equally well everywhere and for every case it is easier to switch between projects using the same tool. And the assume 0 hack isn't useful when switching from real to protected mode while using the code segment you got from the reset vector. Although it is kind of fun running real mode code with a code segment base of 0xffff0000.

Eric

#9 lore raw
In reply to Eric W. Biederman

Hello!

Quoted 3 lines

Given that I want a relative offset, and I have explicitly coded a relative offset, I don't see how that is a hack. I see assembly for is telling the machine explicitly what to do and that does.

No, this is not a relative offset (it would be appropriate if the program tries to relocate itself), but a genuine address in a program which always runs from address 0 (relative to some segment, but it doesn't matter).

Quoted 7 lines

One of the other reasons I want to do it this way is in case is to make copying code easier. If you use idioms that work equally well everywhere and for every case it is easier to switch between projects using the same tool. And the assume 0 hack isn't useful when switching from real to protected mode while using the code segment you got from the reset vector. Although it is kind of fun running real mode code with a code segment base of 0xffff0000.

Agreed, but in this case it's perfectly clear that the code will run from address 0, so it should be written as such.

For such purposes, it would be wonderful if somebody could teach gas how to assemble absolute code and make real location of code and base for calculation of symbols independent. It probably could be done with sections and a cleverly written ldscript (modulo ld bugs), but it's nowhere near elegant.

Have a nice fortnight

Signature · 3 lines
Martin `MJ' Mares   <[email protected]>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
A student who changes the course of history is probably taking an exam.
#10 lore raw
Quoted 5 lines · Martin Mares

For such purposes, it would be wonderful if somebody could teach gas how to assemble absolute code and make real location of code and base for calculation of symbols independent. It probably could be done with sections and a cleverly written ldscript (modulo ld bugs), but it's nowhere near elegant.

The location of code is already independent from symbol addresses. The
default location is identity-mapped to addresses but that can be changed. You normally do that by setting a different LMA in a linker script with the "AT" keyword.

Signature · 3 lines
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: [email protected], PGP key available        +
#11 lore raw
In reply to Eric W. Biederman
Quoted 3 lines · Martin Mares

For such purposes, it would be wonderful if somebody could teach gas how to assemble absolute code and make real location of code and base for calculation of symbols independent.

Agreed. This is what is really wanted for gas to know that %ds points to the start of .text or some other section. This would allow gas to resolve section relative addresses without asking for assistance from the linker. Or if it did ask for assistance the linker could give the desired answer...

Quoted 3 lines

It probably could be done with
sections and a cleverly written ldscript (modulo ld bugs), but it's nowhere near elegant.

I have two ideas to clear up the picture a little, and still retain the full usefulness of the .o files. Since the code is relocatable it is simply nonsense to directly use any of the addresses it exports. All that is interesting are the load addresses, and relative offsets.

replace ``foo - start'' with: ``D(foo)'' where the macro does the work.

Or use a linker script of the form:

.bootsect 0 : AT(0x90000) {
	*(.bootsect)
}
.setup 0 : AT(0x90200) {
	*(.setup)
}

The ld bugs I have seen have mostly been related to choosing file offsets to store the data, and ELF program headers, so I this shouldn't tickle any of ld's bugs.

Which form do you prefer?

Eric