Skip to contentSkip to conversation

Fix GDT limit in setup.S

PATCH In review Coywolf Qi Hunt 6 participants 15 messages Feb 16, 2004 – Feb 25, 2004

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Fix GDT limit in setup.S

Hello 2.4.xx hackers,

In setup.S, i feel like that the gdt limit 0x8000 is not proper and it should be 0x800. How came 0x800 into 0x8000 in 2.4.xx code? Is there a story? It shouldn't be a careless typo. 256 gdt entries should be enough and since it's boot gdt, 256 is ok even if the code is run on SMP with 64 cpus.

At least the comment doesn't match the code. Either fix the code or fix the comment. We really needn't so many GDT entries. Let's use the intel segmentation in a most limited way. Below follows a patch fixing the code.

I don't have the latest 2.4.24, but setup.S isn't changed from 2.4.23 to 2.4.24.

Regards, Coywolf

Signature · 2 lines
Coywolf Qi Hunt
Admin of http://GreatCN.org and http://LoveCN.org
i386/boot/setup.S renamed from i386/boot/setup.S.orig +1 -1
@@ -1093,7 +1093,7 @@
 	.word	0				# idt limit = 0
 	.word	0, 0				# idt base = 0L
 gdt_48:
-	.word	0x8000				# gdt limit=2048,
+	.word	0x800				# gdt limit=2048,
 						#  256 GDT entries
 
 	.word	0, 0				# gdt base (filled in later)
#1 lore raw
Quoted 8 lines · Coywolf Qi Hunt

Hello 2.4.xx hackers,

In setup.S, i feel like that the gdt limit 0x8000 is not proper and it should be 0x800. How came 0x800 into 0x8000 in 2.4.xx code? Is there a story? It shouldn't be a careless typo. 256 gdt entries should be enough and since it's boot gdt, 256 is ok even if the code is run on SMP with 64 cpus.

The first element has nothing to do with the number of GDT entries. It represents the LIMIT. Because the granularity bit is set meaning 4 kilobyte pages and 0x8000 * 0x1000 = 0x8000000

                                      |      |
                                      |      |_______ Page size
                                      |______________ GDT value

This is the size of address space that is unity-mapped for boot.

The granularity is also not the number of GDT entries. It represents the length for which the GDT definition applies.

Because this GDT is used only for booting, somebody decided that there would never be any boot code beyond 2 GB so there was no reason to make room for it. If you change the number to 0x0800, you are declaring that neither the boot code nor any RAM-disk combination will ever exceed 0x800 * 0x1000 = 0x800000 bytes. Therefore you broke my imbedded system. Do not do this.

Quoted 9 lines

At least the comment doesn't match the code. Either fix the code or fix the comment. We really needn't so many GDT entries. Let's use the intel segmentation in a most limited way. Below follows a patch fixing the code.

I don't have the latest 2.4.24, but setup.S isn't changed from 2.4.23 to 2.4.24.

Regards, Coywolf

Cheers,
Dick Johnson
Penguin : Linux version 2.4.24 on an i686 machine (797.90 BogoMips).
Note 96.31% of all statistics are fiction.

#2 lore raw
Quoted 24 lines · Richard B. Johnson
Quoted 8 lines · Coywolf Qi Hunt

Hello 2.4.xx hackers,

In setup.S, i feel like that the gdt limit 0x8000 is not proper and it should be 0x800. How came 0x800 into 0x8000 in 2.4.xx code? Is there a story? It shouldn't be a careless typo. 256 gdt entries should be enough and since it's boot gdt, 256 is ok even if the code is run on SMP with 64 cpus.

The first element has nothing to do with the number of GDT entries. It represents the LIMIT. Because the granularity bit is set meaning 4 kilobyte pages and 0x8000 * 0x1000 = 0x8000000

                                      |      |
                                      |      |_______ Page size
                                      |______________ GDT value

This is the size of address space that is unity-mapped for boot.

The granularity is also not the number of GDT entries. It represents the length for which the GDT definition applies.

Quoted 17 lines

Because this GDT is used only for booting, somebody decided that there would never be any boot code beyond 2 GB so there was no reason to make room for it. If you change the number to 0x0800, you are declaring that neither the boot code nor any RAM-disk combination will ever exceed 0x800 * 0x1000 = 0x800000 bytes. Therefore you broke my imbedded system. Do not do this.

Quoted 9 lines

At least the comment doesn't match the code. Either fix the code or fix the comment. We really needn't so many GDT entries. Let's use the intel segmentation in a most limited way. Below follows a patch fixing the code.

I don't have the latest 2.4.24, but setup.S isn't changed from 2.4.23 to 2.4.24.

Regards, Coywolf

Thank you for you kindly reply, though I really don not agree with you. But thanks very much, since you are the only one replying me. I CCed to all the 2.0 2.2 2.4 maintainers.

Signature · 2 lines
Coywolf Qi Hunt
Admin of http://GreatCN.org and http://LoveCN.org
#3 lore raw

{ Linux not only practical, but an ideal. } Re: [PATCH 2.4.24] Fix GDT limit in setup.S

Quoted 41 lines · Coywolf Qi Hunt
Quoted 39 lines · Richard B. Johnson
Quoted 8 lines · Coywolf Qi Hunt

Hello 2.4.xx hackers,

In setup.S, i feel like that the gdt limit 0x8000 is not proper and it should be 0x800. How came 0x800 into 0x8000 in 2.4.xx code? Is there a story? It shouldn't be a careless typo. 256 gdt entries should be enough and since it's boot gdt, 256 is ok even if the code is run on SMP with 64 cpus.

The first element has nothing to do with the number of GDT entries. It represents the LIMIT. Because the granularity bit is set meaning 4 kilobyte pages and 0x8000 * 0x1000 = 0x8000000

                                      |      |
                                      |      |_______ Page size
                                      |______________ GDT value

This is the size of address space that is unity-mapped for boot.

The granularity is also not the number of GDT entries. It represents the length for which the GDT definition applies.

Because this GDT is used only for booting, somebody decided that there would never be any boot code beyond 2 GB so there was no reason to make room for it. If you change the number to 0x0800, you are declaring that neither the boot code nor any RAM-disk combination will ever exceed 0x800 * 0x1000 = 0x800000 bytes. Therefore you broke my imbedded system. Do not do this.

Quoted 7 lines

At least the comment doesn't match the code. Either fix the code or fix the comment. We really needn't so many GDT entries. Let's use the intel segmentation in a most limited way. Below follows a patch fixing the code.

I don't have the latest 2.4.24, but setup.S isn't changed from 2.4.23 to 2.4.24.

Quoted 8 lines
Quoted 2 lines
Quoted 2 lines

Regards, Coywolf

Thank you for you kindly reply, though I really don not agree with you. But thanks very much, since you are the only one replying me. I CCed to all the 2.0 2.2 2.4 maintainers.

Hello Richard B. Johnson,

I've just find out where the problem lying in your answer, that you are
not talking the same thing as i am. You are talking about the descriptor on which you are quite correct, while I am talking about GDTR, similar to selector, but not selector, could be called `selector' in GDTR. Two different things.

To All Hackers,

plz take my patch to make our kernel more perfect. Linux should be not only practical, but an ideal. And i have more such patches to send.

Regards,
Coywolf

Signature · 2 lines
Coywolf Qi Hunt
Admin of http://GreatCN.org and http://LoveCN.org
#4 lore raw
In reply to Richard B. Johnson
Quoted 24 lines · Richard B. Johnson
Quoted 8 lines · Coywolf Qi Hunt

Hello 2.4.xx hackers,

In setup.S, i feel like that the gdt limit 0x8000 is not proper and it should be 0x800. How came 0x800 into 0x8000 in 2.4.xx code? Is there a story? It shouldn't be a careless typo. 256 gdt entries should be enough and since it's boot gdt, 256 is ok even if the code is run on SMP with 64 cpus.

The first element has nothing to do with the number of GDT entries. It represents the LIMIT. Because the granularity bit is set meaning 4 kilobyte pages and 0x8000 * 0x1000 = 0x8000000

                                      |      |
                                      |      |_______ Page size
                                      |______________ GDT value

This is the size of address space that is unity-mapped for boot.

The granularity is also not the number of GDT entries. It represents the length for which the GDT definition applies.

Quoted 17 lines

Because this GDT is used only for booting, somebody decided that there would never be any boot code beyond 2 GB so there was no reason to make room for it. If you change the number to 0x0800, you are declaring that neither the boot code nor any RAM-disk combination will ever exceed 0x800 * 0x1000 = 0x800000 bytes. Therefore you broke my imbedded system. Do not do this.

Quoted 9 lines

At least the comment doesn't match the code. Either fix the code or fix the comment. We really needn't so many GDT entries. Let's use the intel segmentation in a most limited way. Below follows a patch fixing the code.

I don't have the latest 2.4.24, but setup.S isn't changed from 2.4.23 to 2.4.24.

Regards, Coywolf

Thank you for you kindly reply, though I really don not agree with you. But thanks very much, since you are the only one replying me. I CCed to all the 2.0 2.2 2.4 maintainers.

Signature · 2 lines
Coywolf Qi Hunt
Admin of http://GreatCN.org and http://LoveCN.org
#5 lore raw

[2.0.40 2.2.25 2.4.25] Fix boot GDT limit 0x800 to 0x7ff in setup.S or not

In reply to Coywolf Qi Hunt
Quoted 19 lines · Coywolf Qi Hunt

Hello 2.4.xx hackers,

In setup.S, i feel like that the gdt limit 0x8000 is not proper and it should be 0x800. How came 0x800 into 0x8000 in 2.4.xx code? Is there a story? It shouldn't be a careless typo. 256 gdt entries should be enough and since it's boot gdt, 256 is ok even if the code is run on SMP with 64 cpus. At least the comment doesn't match the code. Either fix the code or fix the comment. We really needn't so many GDT entries. Let's use the intel segmentation in a most limited way. Below follows a patch fixing the code.

I don't have the latest 2.4.24, but setup.S isn't changed from 2.4.23 to 2.4.24.

Regards, Coywolf

------------------------------------------------------------------------

i386/boot/setup.S renamed from i386/boot/setup.S.orig +0 -0
@@ -1093,7 +1093,7 @@
 	.word	0				# idt limit = 0
 	.word	0, 0				# idt base = 0L

gdt_48:

i386/boot/setup.S renamed from i386/boot/setup.S.orig +1 -1
-	.word	0x8000				# gdt limit=2048,
+	.word	0x800				# gdt limit=2048,
Quoted 6 lines
						#  256 GDT entries

	.word	0, 0				# gdt base (filled in later)

Hello all hackers, from 2.0 to 2.4,

In setup.S, from the very beginning (in boot/boot.s for 0.01 kernel), all boot GDT limits are set to 0x800. GDT limit is the LIMIT, not SIZE. So all these 0x800 should be 0x7ff. And actually in the current 2.4.24, it is even an odd 0x8000 which I previously just sent a patch to fix to 0x800. But it should be set to 0x7ff really. Until now only 2.6 sets it properly. Although these will never cause any runtime problem at all, they are ugly. Please consider fix them.

Since it is always 0x800, i even get used to 0x800 rather then the proper 0x7ff. If leave it 0x800, it's useful to distinguish the boot GDT from the later final GDT setting in arch/i386/kernel/head.S. So fix it or not.

Regards,
Coywolf

Signature · 2 lines
Coywolf Qi Hunt
Admin of http://GreatCN.org and http://LoveCN.org
#6 lore raw

Re: [2.0.40 2.2.25 2.4.25] Fix boot GDT limit 0x800 to 0x7ff in setup.S or not

Quoted 38 lines · Coywolf Qi Hunt
Quoted 20 lines · Coywolf Qi Hunt

Hello 2.4.xx hackers,

In setup.S, i feel like that the gdt limit 0x8000 is not proper and it should be 0x800. How came 0x800 into 0x8000 in 2.4.xx code? Is there a story? It shouldn't be a careless typo. 256 gdt entries should be enough and since it's boot gdt, 256 is ok even if the code is run on SMP with 64 cpus. At least the comment doesn't match the code. Either fix the code or fix the comment. We really needn't so many GDT entries. Let's use the intel segmentation in a most limited way. Below follows a patch fixing the code.

I don't have the latest 2.4.24, but setup.S isn't changed from 2.4.23 to 2.4.24.

Regards, Coywolf

------------------------------------------------------------------------

i386/boot/setup.S 2004-02-17 01:15:42.000000000 +0800 renamed from i386/boot/setup.S.orig 2003-11-29 02:26:20.000000000 +0800 +0 -0
@@ -1093,7 +1093,7 @@
    .word    0                # idt limit = 0
    .word    0, 0                # idt base = 0L

gdt_48:

i386/boot/setup.S 2004-02-17 01:15:42.000000000 +0800

Quoted 5 lines
i386/boot/setup.S 2004-02-17 01:15:42.000000000 +0800 renamed from i386/boot/setup.S.orig 2003-11-29 02:26:20.000000000 +0800 +1 -1
-    .word    0x8000                # gdt limit=2048,
+    .word    0x800                # gdt limit=2048,
                        #  256 GDT entries
 
    .word    0, 0                # gdt base (filled in later)

Hello all hackers, from 2.0 to 2.4,

In setup.S, from the very beginning (in boot/boot.s for 0.01 kernel), all boot GDT limits are set to 0x800. GDT limit is the LIMIT, not SIZE. So all these 0x800 should be 0x7ff. And actually in the current 2.4.24, it is even an odd 0x8000 which I previously just sent a patch to fix to 0x800. But it should be set to 0x7ff really. Until now only 2.6 sets it properly. Although these will never cause any runtime problem at all, they are ugly. Please consider fix them.

Quoted 9 lines

Since it is always 0x800, i even get used to 0x800 rather then the proper 0x7ff. If leave it 0x800, it's useful to distinguish the boot GDT from the later final GDT setting in arch/i386/kernel/head.S. So fix it or not.

Regards,
Coywolf

hello,

Since still no one cares, here follows a cut from the intel bible which every one should show his RESPECT to.

IA-32 Intel Architecture Software Developer's Manual Volume 3: System Programming Guide
3.5.1. Segment Descriptor Tables
3-17 Page:81

"Because segment descriptors are always 8 bytes long, the GDT limit should always be one less than an integral multiple of eight(that is, 8N-1)."

Please fix 0x8000 to 0x800 in 2.4, and 0x800 to 0x7ff in 2.0~2.4, ok? This is my last appeal.

Coywolf

Signature · 2 lines
Coywolf Qi Hunt
Admin of http://GreatCN.org and http://LoveCN.org
#7 lore raw

Re: [2.0.40 2.2.25 2.4.25] Fix boot GDT limit 0x800 to 0x7ff in setup.S or not

Quoted 4 lines · Coywolf Qi Hunt

Please fix 0x8000 to 0x800 in 2.4, and 0x800 to 0x7ff in 2.0~2.4, ok? This is my last appeal.

Submit a patch.

-hpa

#8 lore raw

Re: [2.0.40 2.2.25 2.4.25] Fix boot GDT limit 0x800 to 0x7ff in setup.S or not

Quoted 10 lines · H. Peter Anvin
Quoted 4 lines · Coywolf Qi Hunt

Please fix 0x8000 to 0x800 in 2.4, and 0x800 to 0x7ff in 2.0~2.4, ok? This is my last appeal.

Submit a patch.

-hpa

(A patch enclosed for fix 0x800 to 0x7ff for 2.4.25)

Signature · 2 lines
Coywolf Qi Hunt
Admin of http://GreatCN.org and http://LoveCN.org
i386/boot/setup.S renamed from i386/boot/setup.S.orig +1 -1
@@ -1093,7 +1093,7 @@
 	.word	0				# idt limit = 0
 	.word	0, 0				# idt base = 0L
 gdt_48:
-	.word	0x8000				# gdt limit=2048,
+	.word	0x7ff				# gdt limit=2047,
 						#  256 GDT entries
 
 	.word	0, 0				# gdt base (filled in later)
#9 lore raw

PATCH 1/1 Fix GDT limit in setup.S for 2.0 and 2.2

In reply to Coywolf Qi Hunt

Hello,

I posted this problem days ago. Just now I check FreeBSD code and find theirs code goes no this problem. Please take my patches for 2.0 and 2.2 2.4 patch have been already sent to Anvin.

(patches for 2.0 and 2.2 enclosed)

Coywolf

Signature · 2 lines
Coywolf Qi Hunt
Admin of http://GreatCN.org and http://LoveCN.org
setup.S renamed from setup.S.orig +1 -1
@@ -744,7 +744,7 @@
 	.word	0,0			! idt base=0L
 
 gdt_48:
-	.word	0x800		! gdt limit=2048, 256 GDT entries
+	.word	0x7ff		! gdt limit=2047, 256 GDT entries
 	.word	512+gdt,0x9	! gdt base = 0X9xxxx
 
 !
setup.S renamed from setup.S.orig +1 -1
@@ -907,7 +907,7 @@
 	.word	0,0			! idt base=0L
 
 gdt_48:
-	.word	0x800		! gdt limit=2048, 256 GDT entries
+	.word	0x7ff		! gdt limit=2047, 256 GDT entries
 	.word	0, 0		! gdt base (filled in later)
 
 !
#10 lore raw

Re: [PATCH] Fix GDT limit in setup.S for 2.0 and 2.2

Quoted 7 lines · Coywolf Qi Hunt

Hello,

I posted this problem days ago. Just now I check FreeBSD code and find theirs code goes no this problem. Please take my patches for 2.0 and 2.2 2.4 patch have been already sent to Anvin.

(patches for 2.0 and 2.2 enclosed)

Thanks. Note that I'm not due to release the first pre-patch for 2.0.41 in another couple of months (unless some security issue surfaces)

Regards: David Weinehall

Signature · 3 lines
 /) David Weinehall <[email protected]> /) Northern lights wander      (\
//  Maintainer of the v2.0 kernel   //  Dance across the winter sky //
\)  http://www.acc.umu.se/~tao/    (/   Full colour fire           (/
#11 lore raw

Re: [PATCH] Fix GDT limit in setup.S for 2.0 and 2.2

Hi!

Quoted 8 lines
Quoted 5 lines

I posted this problem days ago. Just now I check FreeBSD code and find theirs code goes no this problem. Please take my patches for 2.0 and 2.2 2.4 patch have been already sent to Anvin.

(patches for 2.0 and 2.2 enclosed)

Thanks. Note that I'm not due to release the first pre-patch for 2.0.41 in another couple of months (unless some security issue surfaces)

I do not think that GDT change fixes any real bug. If I were you, I'd reject it for 2.0.
Pavel

Signature · 2 lines
When do you have a heart between your knees?
[Johanka's followup: and *two* hearts?]
#12 lore raw

Re: [PATCH] Fix GDT limit in setup.S for 2.0 and 2.2

In reply to Coywolf Qi Hunt
Quoted 11 lines · Coywolf Qi Hunt

Hello,

I posted this problem days ago. Just now I check FreeBSD code and find theirs code goes no this problem. Please take my patches for 2.0 and 2.2 2.4 patch have been already sent to Anvin.

(patches for 2.0 and 2.2 enclosed)

Coywolf

Please review pages 5-10 thru 5-11 or the Intel 484 Programmer's Reference manual and then tell me what you think you are doing.

Screwing around with that GDT will cause large kernels, i.e., kernels that have RAM disks, to fail to load. I already explained what the elements in the GDT mean. You seem to think you know more than those at Intel who wrote the book.

As the text in page 5-11 shows, if the granularity bit is '1' The limit value is from 4 kilobytes to 4 gigabytes in increments of 4K bytes. You just set that value to 2048 * 4096 = 8,388,608 bytes. This means I can't load a 10 megabyte RAM disk. Stop screwing with the startup code, you absolutely-positively don't have a clue what you are doing.

Cheers,
Dick Johnson
Penguin : Linux version 2.4.24 on an i686 machine (797.90 BogoMips).
Note 96.31% of all statistics are fiction.

#13 lore raw

Re: [PATCH] Fix GDT limit in setup.S for 2.0 and 2.2

Sorry about my last response. I noticed from the code, that the LGDT instruction isn't pointing to where I though it was.

The first WORD (16-bit int) that the LGDT points to is supposed to be the byte-length -1 of the real GDT. The next WORD is supposed to be the low address of the physical location of the real GDT and the next WORD is supposed to be the high address of the physical location of the read GDT.

In the subject code, the real GDT is only 32 bytes in length, the variable you are changing truly should only be 0x1f, the length of the GDT - 1.

Earlier on, I just grabbed your patch and found my kernel wouldn't boot (with 0x800) as the length. This was probably because the current 0x8000, when loaded, creates some kind of alias that lets it work, but changing it to 0x800 removes that alias. Anyway, I am about to boot this system with a mere 0x1f in that entry and see if it even boots.......

Quoted 30 lines · Richard B. Johnson
Quoted 11 lines · Coywolf Qi Hunt

Hello,

I posted this problem days ago. Just now I check FreeBSD code and find theirs code goes no this problem. Please take my patches for 2.0 and 2.2 2.4 patch have been already sent to Anvin.

(patches for 2.0 and 2.2 enclosed)

Coywolf

Please review pages 5-10 thru 5-11 or the Intel 484 Programmer's Reference manual and then tell me what you think you are doing.

Screwing around with that GDT will cause large kernels, i.e., kernels that have RAM disks, to fail to load. I already explained what the elements in the GDT mean. You seem to think you know more than those at Intel who wrote the book.

As the text in page 5-11 shows, if the granularity bit is '1' The limit value is from 4 kilobytes to 4 gigabytes in increments of 4K bytes. You just set that value to 2048 * 4096 = 8,388,608 bytes. This means I can't load a 10 megabyte RAM disk. Stop screwing with the startup code, you absolutely-positively don't have a clue what you are doing.

Quoted 7 lines

Cheers,
Dick Johnson
Penguin : Linux version 2.4.24 on an i686 machine (797.90 BogoMips).
Note 96.31% of all statistics are fiction.

Cheers,
Dick Johnson
Penguin : Linux version 2.4.24 on an i686 machine (797.90 BogoMips).
Note 96.31% of all statistics are fiction.

#14 lore raw

Re: [PATCH] Fix GDT limit in setup.S for 2.0 and 2.2

If you are going to muck with the startup code, I suggest this:

arch/i386/boot/setup.S renamed from arch/i386/boot/setup.S.orig +16 -8
@@ -822,12 +822,16 @@
 a20_done:
 
 # set up gdt and idt
+	movl	$idt_48,%eax			# End of GDT
+	subl	$gdt, %eax			# Subtract beginning
+	decl	%eax				# One less
+	movw	%ax, (gdt_48)			# Length of the table
 	lidt	idt_48				# load idt with 0,0
 	xorl	%eax, %eax			# Compute gdt_base
 	movw	%ds, %ax			# (Convert %ds:gdt to a linear ptr)
 	shll	$4, %eax
 	addl	$gdt, %eax
-	movl	%eax, (gdt_48+2)
+	movl	%eax, (gdt_lo)
 	lgdt	gdt_48				# load gdt with whatever is
 						# appropriate
 
@@ -1080,8 +1084,11 @@
 delay:
 	outb	%al,$0x80
 	ret
-
-# Descriptor tables
+#
+# Descriptor tables, note that more entries will be entered when the
+# kernel starts. However, we do not want to load tables that don't
+# exist at this time!
+#
 gdt:
 	.word	0, 0, 0, 0			# dummy
 	.word	0, 0, 0, 0			# unused
@@ -1100,11 +1107,12 @@
 idt_48:
 	.word	0				# idt limit = 0
 	.word	0, 0				# idt base = 0L
-gdt_48:
-	.word	0x8000				# gdt limit=2048,
-						#  256 GDT entries
-
-	.word	0, 0				# gdt base (filled in later)
+#
+#	Filled in by startup code around label a20_done.
+#
+gdt_48:	.word	0				# Length of GDT -1
+gdt_lo:	.word	0				# GDT base low word
+gdt_hi:	.word	0				# GDT base high word
 
 # Include video setup & detection code
 

FYI, this machine is running with that change. The current code loads a discriptor table with a (non-existant) length of 0x8000 (plus a byte) bytes. For some reason, it's lucky.

Later on, more entries are added and the new table is loaded with another LGDT instruction, fine. But, in the existing code, any "entries" after those shown are video setup code.

The correct code will load the correct table length, not some length that might be used in the future.

Cheers,
Dick Johnson
Penguin : Linux version 2.4.24 on an i686 machine (797.90 BogoMips).
Note 96.31% of all statistics are fiction.