lkml.org 
[lkml]   [1999]   [Aug]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patches in this message
/
Date
From
SubjectKernels > 1M
Hi Peter.

I've now analysed the code, and the enclosed patch does a large part
of what is necessary for the kernel loaders to support kernels over
1023k in size, but it doesn't do all of it. I'd like your comments on
the patch so far, and also on what's left to do.

First, whilst the patch to build.c that you suggested will allow the
kernel to compile ok with `make bzImage`, the resulting kernel will be
unstable and most probably will not work at all.

The reason for this is that the current kernel loader uses the value
of a 16-bit unsigned int in the boot sector as the number of 16-byte
paragraphs of kernel source to load, thus only supporting kernels of
not more than 0xFFFF0 (1,048,560) bytes in size. Worse still, the
value stored in this word is the lower 16 bits of the calculated
value, so if the kernel was, say, 0x107630 (1,078,832) bytes ( in
size, the stored value would be 0x00763 paragraphs, or about 30k !!!

The first hunk of the enclosed patch defines a new 32-bit size field
using four of the previously unused bytes in the boot sector, and
defines this to store the actual kernel size, still measured in 16
byte paragraphs. This field can therefore handle kernels up to 64
Terabytes in size, and it should be a few days before we can produce
kernels that big 8-)))

The second hunk implements all the tweaks to build.c that are needed
for it to correctly fill in this field. As defined, it will record the
correct value in the old field for kernels that are small enough, and
will record 65,535 paragraphs in the old field for kernels that are
too large to be recorded therein.

Note that it IS safe to apply these two hunks to the current kernel,
as the ONLY result will be to actually define the extra field as
mentioned above, and to fill it in when compiling. The resulting
patched kernel will not actually use that field, and the current
1,023k limit will still apply.

The work still to be done is to the actual assembly code in the helper
routine in setup.S along with a small tweak to the code in bootsect.S
but I haven't yet had time to work that part of it out, and I would
definately appreciate your comments thereon. Here's my thoughts,
assuming the above patches have been applied:

1. I would start by applying the following patch to bootsect.S:

Q> @@ -273,8 +273,8 @@
Q> #else
Q> mov ax,es
Q> sub ax,#SYSSEG
Q> -#endif
Q> cmp ax,syssize ! have we loaded all yet?
Q> +#endif
Q> jbe ok1_read
Q> ret
Q> ok1_read:

This has the effect of changing the return value of the helper
function in setup.S such that instead of returning the amount
transferred in AX, it returns with the flags set according to
the results of the relevant comparison, and lets the helper
routine decide exactly how to do the comparison with the actual
kernel size.

To ensure that the rest of the outside routine still works, it
will return with AX holding the smaller of the total number of
paragraphs to go and 65535, ie, it will only hold a value smaller
than 65535 when there are less than 65535 paragraphs still to go.
2. Once this change is finished, the kernel will make absolutely no
use of the old size field, but will depend entirely on the new
size field. This will prevent any problems that might be caused
by code that tweaks the old size field for any reason.

Comments?

Best wishes from Riley.

+----------------------------------------------------------------------+
| There is something frustrating about the quality and speed of Linux |
| development, ie., the quality is too high and the speed is too high, |
| in other words, I can implement this XXXX feature, but I bet someone |
| else has already done so and is just about to release their patch. |
+----------------------------------------------------------------------+
* ftp://ftp.MemAlpha.cx/pub/rhw/Linux
* http://www.MemAlpha.cx/kernel.versions.html--- linux-2.2.10/arch/i386/boot/bootsect.S~ Wed Jun 24 22:30:08 1998
+++ linux-2.2.10/arch/i386/boot/bootsect.S Sat Aug 7 22:32:00 1999
@@ -444,9 +444,12 @@
msg1:
.byte 13,10
.ascii "Loading"

-.org 497
+.org 493
+kernel_size:
+ .word 0
+ .word 0
setup_sects:
.byte SETUPSECS
root_flags:
.word CONFIG_ROOT_RDONLY
--- linux-2.2.10/arch/i386/boot/build.c~ Sun Oct 25 22:16:21 1998
+++ linux-2.2.10/arch/i386/boot/build.c Sat Aug 7 22:35:55 1999
@@ -168,7 +168,7 @@
sz = sb.st_size;
fprintf (stderr, "System is %d kB\n", sz/1024);
sys_size = (sz + 15) / 16;
- if (sys_size > (is_big_kernel ? 0xffff : DEF_SYSSIZE))
+ if (sys_size > (is_big_kernel ? 0xeffff0 : DEF_SYSSIZE))
die("System is too big. Try using %smodules.",
is_big_kernel ? "" : "bzImage or ");
while (sz > 0) {
@@ -187,17 +187,25 @@
}
close(fd);

+ /* Write sizes to the boot sector */
+
- if (lseek(1, 497, SEEK_SET) != 497) /* Write sizes to the boot sector */
+ if (lseek(1, 493, SEEK_SET) != 493)
die("Output: seek failed");
- buf[0] = setup_sectors;
- if (write(1, buf, 1) != 1)
- die("Write of setup sector count failed");
- if (lseek(1, 500, SEEK_SET) != 500)
- die("Output: seek failed");
buf[0] = (sys_size & 0xff);
buf[1] = ((sys_size >> 8) & 0xff);
+ buf[2] = ((sys_size >> 16) & 0xff);
+ buf[3] = ((sys_size >> 24) & 0xff);
+ buf[4] = setup_sectors;
+ if (write(1, buf, 5) != 5)
+ die("Write of extended image size and setup sector count failed");
+ if (lseek(1, 500, SEEK_SET) != 500)
+ die("Output: seek failed");
+ if (sys_size > 65535)
+ buf[0] = buf[1] = 0xff;
if (write(1, buf, 2) != 2)
- die("Write of image length failed");
+ die("Write of compatibility image length failed");
+
+ /* Everything is OK */

- return 0; /* Everything is OK */
+ return 0;
}
\
 
 \ /
  Last update: 2005-03-22 13:53    [W:0.073 / U:0.200 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site