[PATCH] Support for up to 3.5GB RAM on Intel without any config changes

Jakub Jelinek (jj@sunsite.ms.mff.cuni.cz)
Wed, 6 Jan 1999 16:59:16 +0100 (CET)


Hi!

I've ported btfixup (boot time fixup, a way how to finish linking
early during boottime), so that it supports different PAGE_OFFSETs on Intel.
Kernel is always compiled at 0xF0000000 + 1M, so if you have less than
192M of RAM, your apps will e.g. have 3.75GB of virtual address space.
If you have more RAM, it will move PAGE_OFFSET down in 64M steps.
The kernel stays at 0xF0000000 + 1M, so if PAGE_OFFSET is moved, kernel
will be moved physically into different RAM during setup.
I've tested this on a Pentium (well, of course I don't have 2G on any i*86
box around me, it was hard to find some intel box around, so I emulated that
situation), but it has not been tested on i386/i486, where it quite differs
due to missing 4M pages.
Concerning modules, you don't have to recompile them for different
PAGE_OFFSETs as it used to, insmod does everything for you.

Please tell me your comments, send me fix patches and enjoy.
(it is my first ia32 hack after a couple of years SPARC hacking, so the
chance of bugs is higher than usually).

--- linux-2.2.0-pre3/include/asm-i386/page.h.jj Thu Apr 9 03:05:18 1998
+++ linux-2.2.0-pre3/include/asm-i386/page.h Sat Jan 2 12:10:46 1999
@@ -1,6 +1,8 @@
#ifndef _I386_PAGE_H
#define _I386_PAGE_H

+#include <asm/btfixup.h>
+
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT 12
#define PAGE_SIZE (1UL << PAGE_SHIFT)
@@ -58,31 +60,11 @@ typedef unsigned long pgprot_t;
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)

-/*
- * This handles the memory map.. We could make this a config
- * option, but too many people screw it up, and too few need
- * it.
- *
- * A __PAGE_OFFSET of 0xC0000000 means that the kernel has
- * a virtual address space of one gigabyte, which limits the
- * amount of physical memory you can use to about 950MB. If
- * you want to use more physical memory, change this define.
- *
- * For example, if you have 2GB worth of physical memory, you
- * could change this define to 0x70000000, which gives the
- * kernel slightly more than 2GB of virtual memory (enough to
- * map all your physical memory + a bit extra for various
- * io-memory mappings)
- *
- * IF YOU CHANGE THIS, PLEASE ALSO CHANGE
- *
- * arch/i386/vmlinux.lds
- *
- * which has the same constant encoded..
- */
-#define __PAGE_OFFSET (0xC0000000)
+#define KERNBASE 0xF0000000
+
+BTFIXUPDEF_INT_INIT(PAGE_OFFSET,0xF0000000)
+#define PAGE_OFFSET ((unsigned long)BTFIXUP_INT_INIT(PAGE_OFFSET,0xF0000000))

-#define PAGE_OFFSET ((unsigned long)__PAGE_OFFSET)
#define __pa(x) ((unsigned long)(x)-PAGE_OFFSET)
#define __va(x) ((void *)((unsigned long)(x)+PAGE_OFFSET))
#define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT)
--- linux-2.2.0-pre3/include/asm-i386/io.h.jj Fri Jan 1 20:56:23 1999
+++ linux-2.2.0-pre3/include/asm-i386/io.h Sat Jan 2 12:29:27 1999
@@ -101,8 +101,8 @@ __OUTS(l)
#include <linux/vmalloc.h>
#include <asm/page.h>

-#define __io_virt(x) ((void *)(PAGE_OFFSET | (unsigned long)(x)))
-#define __io_phys(x) ((unsigned long)(x) & ~PAGE_OFFSET)
+#define __io_virt(x) ((void *)(PAGE_OFFSET + (unsigned long)(x)))
+#define __io_phys(x) ((unsigned long)(x) - PAGE_OFFSET)
/*
* Change virtual addresses to physical addresses and vv.
* These are pretty trivial
--- linux-2.2.0-pre3/include/asm-i386/pgtable.h.jj Fri Jan 1 20:53:34 1999
+++ linux-2.2.0-pre3/include/asm-i386/pgtable.h Sat Jan 2 12:29:27 1999
@@ -180,22 +180,22 @@ static inline void flush_tlb_range(struc
#define PGDIR_MASK (~(PGDIR_SIZE-1))

/*
+ * pgd entries used up by user/kernel:
+ */
+
+BTFIXUPDEF_INT_INIT(USER_PGD_PTRS,0x3C0)
+#define USER_PGD_PTRS ((unsigned long)BTFIXUP_INT_INIT(USER_PGD_PTRS,0x3C0))
+BTFIXUPDEF_INT_INIT(KERNEL_PGD_PTRS,0x40)
+#define KERNEL_PGD_PTRS BTFIXUP_INT_INIT(KERNEL_PGD_PTRS,0x40)
+
+/*
* entries per page directory level: the i386 is two-level, so
* we don't really have any PMD directory physically.
*/
#define PTRS_PER_PTE 1024
#define PTRS_PER_PMD 1
#define PTRS_PER_PGD 1024
-#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE)
-
-/*
- * pgd entries used up by user/kernel:
- */
-
-#define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT)
-#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS)
-#define __USER_PGD_PTRS ((__PAGE_OFFSET >> PGDIR_SHIFT) & 0x3ff)
-#define __KERNEL_PGD_PTRS (PTRS_PER_PGD-__USER_PGD_PTRS)
+#define USER_PTRS_PER_PGD USER_PGD_PTRS

#ifndef __ASSEMBLY__
/* Just any arbitrary offset to the start of the vmalloc VM area: the
--- linux-2.2.0-pre3/include/asm-i386/processor.h.jj Fri Jan 1 20:53:34 1999
+++ linux-2.2.0-pre3/include/asm-i386/processor.h Sat Jan 2 12:29:26 1999
@@ -11,6 +11,7 @@
#include <asm/math_emu.h>
#include <asm/segment.h>
#include <asm/page.h>
+#include <asm/btfixup.h>

/*
* CPU type and hardware bug flags. Kept separately for each CPU.
@@ -150,14 +151,15 @@ extern unsigned int machine_submodel_id;
extern unsigned int BIOS_revision;

/*
- * User space process size: 3GB (default).
+ * User space process size: 3.75GB (default).
*/
#define TASK_SIZE (PAGE_OFFSET)

/* This decides where the kernel will search for a free chunk of vm
* space during mmap's.
*/
-#define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
+BTFIXUPDEF_INT_INIT(TASK_UNMAPPED_BASE,0x50000000)
+#define TASK_UNMAPPED_BASE BTFIXUP_INT_INIT(TASK_UNMAPPED_BASE,0x50000000)

/*
* Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
@@ -245,7 +247,7 @@ struct thread_struct {
sizeof(init_stack) + (long) &init_stack, /* esp0 */ \
__KERNEL_DS, 0, /* ss0 */ \
0,0,0,0,0,0, /* stack1, stack2 */ \
- (long) &swapper_pg_dir - PAGE_OFFSET, /* cr3 */ \
+ (long) &swapper_pg_dir, /* cr3 */ \
0,0, /* eip,eflags */ \
0,0,0,0, /* eax,ecx,edx,ebx */ \
0,0,0,0, /* esp,ebp,esi,edi */ \
--- linux-2.2.0-pre3/include/asm-i386/btfixup.h.jj Sat Jan 2 12:10:46 1999
+++ linux-2.2.0-pre3/include/asm-i386/btfixup.h Sat Jan 2 12:10:46 1999
@@ -0,0 +1,79 @@
+/* $Id: btfixup.h,v 1.4 1998/03/09 14:04:43 jj Exp $
+ * asm-i386/btfixup.h: Macros for boot time linking.
+ *
+ * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#ifndef _SPARC_BTFIXUP_H
+#define _SPARC_BTFIXUP_H
+
+#include <linux/init.h>
+
+#ifndef __ASSEMBLY__
+
+/* Fixup call xx */
+
+#define BTFIXUPDEF_CALL(__type, __name, __args...) \
+ extern __type ___f_##__name(__args); \
+ extern unsigned ___fs_##__name[3];
+#define BTFIXUPDEF_CALL_CONST(__type, __name, __args...) \
+ extern __type ___f_##__name(__args) __attribute__((const)); \
+ extern unsigned ___fs_##__name[3];
+#define BTFIXUP_CALL(__name) ___f_##__name
+
+/* Put a full 32bit integer into some register variable */
+
+#define BTFIXUPDEF_INT(__name) \
+ extern unsigned char ___i_##__name; \
+ extern unsigned ___is_##__name[2];
+#define BTFIXUPDEF_INT_INIT(__name,__val) \
+ extern unsigned char ___i_##__name##__btset_##__val; \
+ extern unsigned ___is_##__name[2];
+#define BTFIXUP_INT(__name) ((unsigned int)&___i_##__name)
+#define BTFIXUP_INT_INIT(__name,__val) ((unsigned int)&___i_##__name##__btset_##__val)
+#define BTFIXUP_EXP_INT(__name) ___i_##__name
+#define BTFIXUP_EXP_INT_INIT(__name,__val) ___i_##__name##__btset_##__val
+
+#define BTFIXUPCALL_NORM 0x00000000 /* Always call */
+
+#define BTFIXUPSET_CALL(__name, __addr, __insn) \
+ do { \
+ ___fs_##__name[0] |= 1; \
+ ___fs_##__name[1] = (unsigned long)__addr; \
+ ___fs_##__name[2] = __insn; \
+ } while (0)
+
+#define BTFIXUPCOPY_CALL(__name, __from) \
+ do { \
+ ___fs_##__name[0] |= 1; \
+ ___fs_##__name[1] = ___fs_##__from[1]; \
+ ___fs_##__name[2] = ___fs_##__from[2]; \
+ } while (0)
+
+#define BTFIXUPSET_INT(__name, __val) \
+ do { \
+ ___is_##__name[0] |= 1; \
+ ___is_##__name[1] = (unsigned)__val; \
+ } while (0)
+
+#define BTFIXUPCOPY_INT(__name, __from) \
+ do { \
+ ___is_##__name[0] |= 1; \
+ ___is_##__name[1] = ___is_##__from[1]; \
+ } while (0)
+
+#define BTFIXUPVAL_CALL(__name) \
+ ((unsigned long)___fs_##__name[1])
+
+extern void btfixup(void);
+
+#else /* __ASSEMBLY__ */
+
+#define BTFIXUP_INT(__name) ___i_ ## __name
+#define BTFIXUP_INT_INIT(__name,__val) ___i_ ## __name ## __btset_ ## __val
+#define BTFIXUPDEF_INT(__name)
+#define BTFIXUPDEF_INT_INIT(__name,__val)
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* !(_SPARC_BTFIXUP_H) */
--- linux-2.2.0-pre3/include/asm-i386/elf.h.jj Wed Dec 30 20:34:24 1998
+++ linux-2.2.0-pre3/include/asm-i386/elf.h Sat Jan 2 12:35:00 1999
@@ -51,7 +51,13 @@ typedef struct user_i387_struct elf_fpre
the loader. We need to make sure that it is out of the way of the program
that it will "exec", and that there is sufficient room for the brk. */

-#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
+#ifdef __KERNEL__
+#include <asm/btfixup.h>
+BTFIXUPDEF_INT_INIT(ELF_ET_DYN_BASE,0xA0000000)
+#define ELF_ET_DYN_BASE BTFIXUP_INT_INIT(ELF_ET_DYN_BASE,0xA0000000)
+#else
+#define ELF_ET_DYN_BASE 0xA0000000
+#endif

/* Wow, the "main" arch needs arch dependent functions too.. :) */

--- linux-2.2.0-pre3/arch/i386/boot/btfixupprep.c.jj Sat Jan 2 12:10:46 1999
+++ linux-2.2.0-pre3/arch/i386/boot/btfixupprep.c Sat Jan 2 12:10:46 1999
@@ -0,0 +1,314 @@
+/* $Id: btfixupprep.c,v 1.5 1998/09/16 12:24:55 jj Exp $
+ Simple utility to prepare vmlinux image for i386.
+ Resolves all BTFIXUP uses and settings and creates
+ a special .s object to link to the image.
+
+ Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <malloc.h>
+
+#define MAXSYMS 1024
+
+static char *symtab = "SYMBOL TABLE:";
+static char *relrec = "RELOCATION RECORDS FOR [";
+static int rellen;
+static int symlen;
+int mode;
+
+struct _btfixup;
+
+typedef struct _btfixuprel {
+ char *sect;
+ unsigned long offset;
+ struct _btfixup *f;
+ int frel;
+ struct _btfixuprel *next;
+} btfixuprel;
+
+typedef struct _btfixup {
+ int type;
+ int setinitval;
+ unsigned int initval;
+ char *initvalstr;
+ char *name;
+ btfixuprel *rel;
+} btfixup;
+
+btfixup array[MAXSYMS];
+int last = 0;
+char buffer[1024];
+unsigned long lastfoffset = -1;
+unsigned long lastfrelno;
+btfixup *lastf;
+
+void fatal(void) __attribute__((noreturn));
+void fatal(void)
+{
+ fprintf(stderr, "Malformed output from objdump\n%s\n", buffer);
+ exit(1);
+}
+
+btfixup *find(int type, char *name)
+{
+ int i;
+ for (i = 0; i < last; i++) {
+ if (array[i].type == type && !strcmp(array[i].name, name))
+ return array + i;
+ }
+ array[last].type = type;
+ array[last].name = strdup(name);
+ array[last].setinitval = 0;
+ if (!array[last].name) fatal();
+ array[last].rel = NULL;
+ last++;
+ if (last >= MAXSYMS) {
+ fprintf(stderr, "Ugh. Something strange. More than %d different BTFIXUP symbols\n", MAXSYMS);
+ exit(1);
+ }
+ return array + last - 1;
+}
+
+int main(int argc,char **argv)
+{
+ char *p, *q;
+ char *sect;
+ int i, j, k;
+ unsigned int initval;
+ int shift;
+ btfixup *f;
+ btfixuprel *r, **rr;
+ unsigned long offset;
+ char *initvalstr;
+
+ symlen = strlen(symtab);
+ while (fgets (buffer, 1024, stdin) != NULL)
+ if (!strncmp (buffer, symtab, symlen))
+ goto main0;
+ fatal();
+main0:
+ if (fgets (buffer, 1024, stdin) == NULL || buffer[0] < '0' || buffer[0] > '9')
+ fatal();
+ for (mode = 0;; mode++)
+ if (buffer[mode] < '0' || buffer[mode] > '9')
+ break;
+ if (mode != 8 && mode != 16)
+ fatal();
+
+ rellen = strlen(relrec);
+ while (fgets (buffer, 1024, stdin) != NULL)
+ if (!strncmp (buffer, relrec, rellen))
+ goto main1;
+ fatal();
+main1:
+ sect = malloc(strlen (buffer + rellen) + 1);
+ if (!sect) fatal();
+ strcpy (sect, buffer + rellen);
+ p = strchr (sect, ']');
+ if (!p) fatal();
+ *p = 0;
+ if (fgets (buffer, 1024, stdin) == NULL)
+ fatal();
+ while (fgets (buffer, 1024, stdin) != NULL) {
+ int nbase;
+ if (!strncmp (buffer, relrec, rellen))
+ goto main1;
+ p = strchr (buffer, '\n');
+ if (p) *p = 0;
+ if (strlen (buffer) < 22+mode)
+ continue;
+ if (strncmp (buffer + mode, " R_386_", 7))
+ continue;
+ nbase = 27 - 8 + mode;
+ if (buffer[nbase] != '_' || buffer[nbase+1] != '_' || buffer[nbase+2] != '_')
+ continue;
+ switch (buffer[nbase+3]) {
+#if 0
+ case 'f': /* CALL */
+#endif
+ case 'i': /* INT */
+ break;
+ default:
+ continue;
+ }
+ p = strchr (buffer + nbase+5, '+');
+ if (p) *p = 0;
+ shift = nbase + 5;
+ if (buffer[nbase+4] == 's' && buffer[nbase+5] == '_') {
+ shift = nbase + 6;
+ if (strcmp (sect, ".text.init")) {
+ fprintf(stderr, "Wrong use of '%s' BTFIXUPSET.\nBTFIXUPSET_CALL can be used only in __init sections\n", buffer+shift);
+ exit(1);
+ }
+ } else if (buffer[nbase+4] != '_')
+ continue;
+ if (strcmp (sect, ".text") && strcmp (sect, ".text.init") && strcmp (sect, ".fixup") && strcmp (sect, "__ksymtab")) {
+ fprintf(stderr, "Wrong use of '%s' in '%s' section. It can be only used in .text, .text.init, .fixup and __ksymtab\n", buffer + shift, sect);
+ exit(1);
+ }
+ p = strstr (buffer + shift, "__btset_");
+ if (p && buffer[nbase+4] == 's') {
+ fprintf(stderr, "__btset_ in BTFIXUP name can only be used when defining the variable, not for setting\n%s\n", buffer);
+ exit(1);
+ }
+ initval = 0;
+ initvalstr = NULL;
+ if (p) {
+ if (p[8] != '0' || p[9] != 'x') {
+ fprintf(stderr, "Pre-initialized values can be only initialized with hexadecimal constants starting 0x\n%s\n", buffer);
+ exit(1);
+ }
+ initval = strtoul(p + 10, &q, 16);
+ if (*q || !initval) {
+ fprintf(stderr, "Pre-initialized values can be only in the form name__btset_0xXXXXXXXX where X are hex digits.\nThey cannot be name__btset_0x00000000 though. Use BTFIXUPDEF_XX instead of BTFIXUPDEF_XX_INIT then.\n%s\n", buffer);
+ exit(1);
+ }
+ initvalstr = p + 10;
+ *p = 0;
+ }
+ f = find(buffer[nbase+3], buffer + shift);
+ if (buffer[nbase+4] == 's')
+ continue;
+ switch (buffer[nbase+3]) {
+#if 0
+ case 'f':
+ if (initval) {
+ fprintf(stderr, "Cannot use pre-initalized fixups for calls\n%s\n", buffer);
+ exit(1);
+ }
+ if (!strcmp (sect, "__ksymtab")) {
+ if (strncmp (buffer + mode+7, "32 ", 10)) {
+ fprintf(stderr, "BTFIXUP_CALL in EXPORT_SYMBOL results in relocation other than R_386_32\n\%s\n", buffer);
+ exit(1);
+ }
+ } else if (strncmp (buffer + mode+7, "PC32 ", 10) &&
+ strncmp (buffer + mode+7, "32 ", 10)) {
+ fprintf(stderr, "BTFIXUP_CALL results in relocation other than R_386_32 or R_386_PC32\n%s\n", buffer);
+ exit(1);
+ }
+ break;
+#endif
+ case 'i':
+ if (strncmp (buffer + mode+7, "32 ", 10)) {
+ fprintf(stderr, "BTFIXUP_INT results in relocation other than R_386_32\n%s\n", buffer);
+ exit(1);
+ }
+ break;
+ }
+ if (!f->setinitval) {
+ f->initval = initval;
+ if (initvalstr) {
+ f->initvalstr = strdup(initvalstr);
+ if (!f->initvalstr) fatal();
+ }
+ f->setinitval = 1;
+ } else if (f->initval != initval) {
+ fprintf(stderr, "Btfixup %s previously used with initializer %s which doesn't match with current initializer\n%s\n",
+ f->name, f->initvalstr ? : "0x00000000", buffer);
+ exit(1);
+ } else if (initval && strcmp(f->initvalstr, initvalstr)) {
+ fprintf(stderr, "Btfixup %s previously used with initializer %s which doesn't match with current initializer.\n"
+ "Initializers have to match literally as well.\n%s\n",
+ f->name, f->initvalstr, buffer);
+ exit(1);
+ }
+ offset = strtoul(buffer, &q, 16);
+ if (q != buffer + mode || (!offset && (mode == 8 ? strncmp (buffer, "00000000 ", 9) : strncmp (buffer, "0000000000000000 ", 17)))) {
+ fprintf(stderr, "Malformed relocation address in\n%s\n", buffer);
+ exit(1);
+ }
+ for (k = 0, r = f->rel, rr = &f->rel; r; rr = &r->next, r = r->next, k++)
+ if (r->offset == offset && !strcmp(r->sect, sect)) {
+ fprintf(stderr, "Ugh. One address has two relocation records\n");
+ exit(1);
+ }
+ *rr = malloc(sizeof(btfixuprel));
+ if (!*rr) fatal();
+ (*rr)->offset = offset;
+ (*rr)->f = NULL;
+ if (buffer[nbase+3] == 'f') {
+ lastf = f;
+ lastfoffset = offset;
+ lastfrelno = k;
+ } else if (lastfoffset + 4 == offset) {
+ (*rr)->f = lastf;
+ (*rr)->frel = lastfrelno;
+ }
+ (*rr)->sect = sect;
+ (*rr)->next = NULL;
+ }
+ printf("# Generated by btfixupprep. Do not edit.\n\n");
+ printf("\t.section\t.data.init,\"aw\"\n\t.align\t2\n\n");
+ printf("\t.global\t___btfixup_start\n___btfixup_start:\n\n");
+ for (i = 0; i < last; i++) {
+ f = array + i;
+ printf("\t.global\t___%cs_%s\n", f->type, f->name);
+ if (f->type == 'f')
+ printf("___%cs_%s:\n\t.long 0x%08x,0,0,", f->type, f->name, f->type << 24);
+ else
+ printf("___%cs_%s:\n\t.long 0x%08x,0,0x%08x,", f->type, f->name, f->type << 24, f->initval);
+ for (j = 0, r = f->rel; r != NULL; j++, r = r->next);
+ if (j)
+ printf("%d\n\t.long\t", j);
+ else
+ printf("0\n");
+ for (r = f->rel, j--; r != NULL; j--, r = r->next) {
+ if (!strcmp (r->sect, ".text"))
+ printf ("_stext+0x%08lx", r->offset);
+ else if (!strcmp (r->sect, ".text.init"))
+ printf ("__init_begin+0x%08lx", r->offset);
+ else if (!strcmp (r->sect, "__ksymtab"))
+ printf ("__start___ksymtab+0x%08lx", r->offset);
+ else if (!strcmp (r->sect, ".fixup"))
+ printf ("__start___fixup+0x%08lx", r->offset);
+ else
+ fatal();
+ if (j) printf (",");
+ else printf ("\n");
+ }
+ printf("\n");
+ }
+ printf("\n\t.global\t___btfixup_end\n___btfixup_end:\n");
+ printf("\n\n# Define undefined references\n\n");
+ for (i = 0; i < last; i++) {
+ f = array + i;
+ if (f->type == 'f') {
+ printf("\t.global\t___f_%s\n", f->name);
+ printf("___f_%s:\n", f->name);
+ }
+ }
+ printf("\tret\n\n");
+ for (i = 0; i < last; i++) {
+ f = array + i;
+ if (f->type != 'f') {
+ if (!f->initval) {
+ printf("\t.global\t___%c_%s\n", f->type, f->name);
+ printf("___%c_%s = 0\n", f->type, f->name);
+ } else {
+ printf("\t.global\t___%c_%s__btset_0x%s\n", f->type, f->name, f->initvalstr);
+ printf("___%c_%s__btset_0x%s = 0x%08x\n", f->type, f->name, f->initvalstr, f->initval);
+ }
+ }
+ }
+ printf("\n\n");
+ exit(0);
+}
--- linux-2.2.0-pre3/arch/i386/boot/Makefile.jj Mon Jul 20 19:05:15 1998
+++ linux-2.2.0-pre3/arch/i386/boot/Makefile Sat Jan 2 12:10:46 1999
@@ -81,10 +81,20 @@ bbootsect.o: bbootsect.s
bbootsect.s: bootsect.S Makefile $(BOOT_INCL)
$(CPP) -D__BIG_KERNEL__ -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@

+btfixupprep: btfixupprep.c
+ $(HOSTCC) $(HOSTCFLAGS) -o btfixupprep btfixupprep.c
+
+btfix.s: btfixupprep $(TOPDIR)/vmlinux.o
+ $(OBJDUMP) -x $(TOPDIR)/vmlinux.o | ./btfixupprep > btfix.s
+
+btfix.o: btfix.s
+ $(CC) -c -o btfix.o btfix.s
+
dep:

clean:
rm -f tools/build
rm -f setup bootsect zImage compressed/vmlinux.out
rm -f bsetup bbootsect bzImage compressed/bvmlinux.out
+ rm -f btfixupprep btfix.o btfix.s
@$(MAKE) -C compressed clean
--- linux-2.2.0-pre3/arch/i386/mm/btfixup.c.jj Sat Jan 2 12:10:46 1999
+++ linux-2.2.0-pre3/arch/i386/mm/btfixup.c Sat Jan 2 12:10:46 1999
@@ -0,0 +1,77 @@
+/* $Id: btfixup.c,v 1.7 1998/03/09 14:03:56 jj Exp $
+ * btfixup.c: Boot time code fixup and relocator.
+ *
+ * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <asm/btfixup.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+extern unsigned int ___btfixup_start[], ___btfixup_end[], __init_begin[], __init_end[], __init_text_end[];
+extern unsigned int _stext[], _end[], __start___ksymtab[], __stop___ksymtab[];
+#if 0
+static char wrong_f[] __initdata = "Trying to set f fixup %p to invalid function %08x\n";
+#endif
+static char wrong[] __initdata = "Wrong address for %c fixup %p\n";
+
+static __inline__ void set_addr(unsigned int *addr, unsigned int q1, unsigned int value)
+{
+ *addr = value;
+}
+
+__initfunc(void btfixup(void))
+{
+ unsigned int *p, *q;
+ int type, count;
+ unsigned *addr;
+
+ for (p = ___btfixup_start; p < ___btfixup_end; ) {
+ count = p[3];
+ q = p + 4;
+ type = ((unsigned char *)p)[3];
+#if 0
+ switch (type) {
+ case 'f':
+ if ((p[0] & 1)
+ && ((unsigned *)(p[1]) < _stext || (unsigned *)(p[1]) >= _end)) {
+ printk(wrong_f, p, p[1]);
+ return;
+ }
+ break;
+ }
+#endif
+ if (p[0] & 1) {
+ p[0] &= ~1;
+ while (count) {
+ addr = (unsigned *)*q;
+ if (addr < _stext || addr >= _end) {
+ printk(wrong, type, p);
+ return;
+ }
+ switch (type) {
+#if 0
+ case 'f': /* CALL */
+ break;
+#endif
+ case 'i': /* INT */
+ *addr += p[1] - p[2];
+ break;
+ }
+ count--;
+ q++;
+ }
+ switch (type) {
+ case 'i':
+ p[2] = p[1];
+ break;
+ }
+ } else
+ p = q + count;
+ }
+}
--- linux-2.2.0-pre3/arch/i386/mm/init.c.jj Fri Jan 1 20:07:43 1999
+++ linux-2.2.0-pre3/arch/i386/mm/init.c Tue Jan 5 00:46:44 1999
@@ -200,7 +200,7 @@ extern char __init_begin, __init_end;
*/
unsigned long mmu_cr4_features __initdata = 0;

-static inline void set_in_cr4(unsigned long mask)
+void __init set_in_cr4(unsigned long mask)
{
mmu_cr4_features |= mask;
__asm__("movl %%cr4,%%eax\n\t"
@@ -265,7 +265,7 @@ void set_fixmap (enum fixed_addresses id
* This routines also unmaps the page at virtual kernel address 0, so
* that we can trap those pesky NULL-reference errors in the kernel.
*/
-__initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_mem))
+unsigned long __init paging_init(unsigned long start_mem, unsigned long end_mem)
{
pgd_t * pg_dir;
pte_t * pg_table;
@@ -319,8 +319,7 @@ __initfunc(unsigned long paging_init(uns
pgd_val(pg_dir[0]) = 0;

/* Map whole memory from PAGE_OFFSET */
- pg_dir += USER_PGD_PTRS;
- while (address < end_mem) {
+ if (boot_cpu_data.x86_capability & X86_FEATURE_PSE) {
/*
* If we're running on a Pentium CPU, we can use the 4MB
* page tables.
@@ -329,11 +328,13 @@ __initfunc(unsigned long paging_init(uns
* virtual memory boundary, but that's OK as we won't
* use that memory anyway.
*/
- if (boot_cpu_data.x86_capability & X86_FEATURE_PSE) {
+ pg_dir += USER_PGD_PTRS;
+ set_in_cr4(X86_CR4_PSE);
+ boot_cpu_data.wp_works_ok = 1;
+
+ while (address < end_mem) {
unsigned long __pe;

- set_in_cr4(X86_CR4_PSE);
- boot_cpu_data.wp_works_ok = 1;
__pe = _KERNPG_TABLE + _PAGE_4M + __pa(address);
/* Make it "global" too if supported */
if (boot_cpu_data.x86_capability & X86_FEATURE_PGE) {
@@ -342,31 +343,42 @@ __initfunc(unsigned long paging_init(uns
}
pgd_val(*pg_dir) = __pe;
pg_dir++;
- address += 4*1024*1024;
- continue;
+ address += PGDIR_SIZE;
}
-
+ } else {
/*
* We're on a [34]86, use normal page tables.
- * pg_table is physical at this point
+ * If PAGE_OFFSET != KERNBASE, we might run with start_mem
+ * out of the 4M from KERNBASE, while that area would not be
+ * mapped yet. So we have to go downwards.
*/
- pg_table = (pte_t *) (PAGE_MASK & pgd_val(*pg_dir));
- if (!pg_table) {
- pg_table = (pte_t *) __pa(start_mem);
- start_mem += PAGE_SIZE;
- }
+ address = end_mem & PGDIR_MASK;
+ if (end_mem & ~PGDIR_MASK)
+ address -= PGDIR_SIZE;
+ pg_dir += address >> PGDIR_SHIFT;
+ while (address >= PAGE_OFFSET) {
+ /*
+ * pg_table is physical at this point
+ */
+ pg_table = (pte_t *) (PAGE_MASK & pgd_val(*pg_dir));
+ if (!pg_table) {
+ pg_table = (pte_t *) __pa(start_mem);
+ start_mem += PAGE_SIZE;
+ }

- pgd_val(*pg_dir) = _PAGE_TABLE | (unsigned long) pg_table;
- pg_dir++;
+ pgd_val(*pg_dir) = _PAGE_TABLE | (unsigned long) pg_table;
+ pg_dir++;

- /* now change pg_table to kernel virtual addresses */
- pg_table = (pte_t *) __va(pg_table);
- for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) {
- pte_t pte = mk_pte(address, PAGE_KERNEL);
- if (address >= end_mem)
- pte_val(pte) = 0;
- set_pte(pg_table, pte);
- address += PAGE_SIZE;
+ /* now change pg_table to kernel virtual addresses */
+ pg_table = (pte_t *) __va(pg_table);
+ for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) {
+ pte_t pte = mk_pte(address, PAGE_KERNEL);
+ if (address >= end_mem)
+ pte_val(pte) = 0;
+ set_pte(pg_table, pte);
+ address += PAGE_SIZE;
+ }
+ address -= 2 * PGDIR_SIZE;
}
}
start_mem = fixmap_init(start_mem);
@@ -384,7 +396,7 @@ __initfunc(unsigned long paging_init(uns
* before and after the test are here to work-around some nasty CPU bugs.
*/

-__initfunc(void test_wp_bit(void))
+void __init test_wp_bit(void)
{
unsigned char tmp_reg;
unsigned long old = pg0[0];
@@ -415,7 +427,7 @@ __initfunc(void test_wp_bit(void))
printk(".\n");
}

-__initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
+void __init mem_init(unsigned long start_mem, unsigned long end_mem)
{
unsigned long start_low_mem = PAGE_SIZE;
int codepages = 0;
@@ -452,6 +464,12 @@ __initfunc(void mem_init(unsigned long s
* controller as well..
*/
while (start_low_mem < 0x9f000+PAGE_OFFSET) {
+ clear_bit(PG_reserved, &mem_map[MAP_NR(start_low_mem)].flags);
+ start_low_mem += PAGE_SIZE;
+ }
+
+ start_low_mem = PAGE_OFFSET+0x100000;
+ while (start_low_mem < KERNBASE+0x100000) {
clear_bit(PG_reserved, &mem_map[MAP_NR(start_low_mem)].flags);
start_low_mem += PAGE_SIZE;
}
--- linux-2.2.0-pre3/arch/i386/mm/Makefile.jj Fri Nov 1 10:56:43 1996
+++ linux-2.2.0-pre3/arch/i386/mm/Makefile Sat Jan 2 12:10:46 1999
@@ -8,6 +8,6 @@
# Note 2! The CFLAGS definition is now in the main makefile...

O_TARGET := mm.o
-O_OBJS := init.o fault.o ioremap.o extable.o
+O_OBJS := init.o fault.o ioremap.o extable.o btfixup.o

include $(TOPDIR)/Rules.make
--- linux-2.2.0-pre3/arch/i386/kernel/setup.c.jj Thu Dec 31 20:55:19 1998
+++ linux-2.2.0-pre3/arch/i386/kernel/setup.c Wed Jan 6 17:59:14 1999
@@ -34,6 +34,7 @@
#endif
#include <asm/processor.h>
#include <linux/console.h>
+#include <linux/elf.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -110,14 +111,18 @@ extern unsigned long cpu_hz;

static char command_line[COMMAND_LINE_SIZE] = { 0, };
char saved_command_line[COMMAND_LINE_SIZE];
+
+#define VMALLOC_RESERVE (64 << 20) /* 64MB for vmalloc */
+#define MAXMEM ((unsigned long)(-KERNBASE-VMALLOC_RESERVE))

-__initfunc(void setup_arch(char **cmdline_p,
- unsigned long * memory_start_p, unsigned long * memory_end_p))
+void __init setup_arch(char **cmdline_p,
+ unsigned long * memory_start_p, unsigned long * memory_end_p)
{
unsigned long memory_start, memory_end;
char c = ' ', *to = command_line, *from = COMMAND_LINE;
int len = 0;
static unsigned char smptrap=0;
+ unsigned long page_offset = KERNBASE;

if (smptrap)
return;
@@ -159,7 +164,6 @@ __initfunc(void setup_arch(char **cmdlin
init_task.mm->end_code = (unsigned long) &_etext;
init_task.mm->end_data = (unsigned long) &_edata;
init_task.mm->brk = (unsigned long) &_end;
-
/* Save unparsed command line copy for /proc/cmdline */
memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
@@ -195,24 +199,76 @@ __initfunc(void setup_arch(char **cmdlin
}
*to = '\0';
*cmdline_p = command_line;
-
-#define VMALLOC_RESERVE (64 << 20) /* 64MB for vmalloc */
-#define MAXMEM ((unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE))
-
- if (memory_end > MAXMEM)
- {
- memory_end = MAXMEM;
- printk(KERN_WARNING "Warning only %ldMB will be used.\n",
- MAXMEM>>20);
+
+ if (memory_end > MAXMEM) {
+ /* Ok, move PAGE_OFFSET and relocate ourselves.
+ * This has to be done as early as possible, so we don't
+ * wait even till paging_init. We have to move all the
+ * kernel code and data physically.
+ */
+ unsigned long kern_phys;
+ unsigned long user_pgd_ptrs;
+ unsigned long kern_pg0 = 0;
+ pgd_t kern_pgd, kern_pgd_after;
+ extern void move_kernel(pgd_t kern_pgd, unsigned long count,
+ unsigned long kern_phys, pgd_t kern_pgd_after);
+
+ /* We need to make sure some virtual memory is kept for userland */
+ if (memory_end > 0xE0000000)
+ memory_end = 0xE0000000;
+ page_offset = -((memory_end + 0x3FFFFFF) & ~0x3FFFFFF) - VMALLOC_RESERVE;
+ BTFIXUPSET_INT(PAGE_OFFSET, page_offset);
+ BTFIXUPSET_INT(TASK_UNMAPPED_BASE, page_offset / 3);
+ BTFIXUPSET_INT(ELF_ET_DYN_BASE, 2 * (page_offset / 3));
+ user_pgd_ptrs = page_offset >> PGDIR_SHIFT;
+ BTFIXUPSET_INT(USER_PGD_PTRS, user_pgd_ptrs);
+ BTFIXUPSET_INT(KERNEL_PGD_PTRS, PTRS_PER_PGD-user_pgd_ptrs);
+ kern_phys = KERNBASE - page_offset;
+ swapper_pg_dir[user_pgd_ptrs] = __pgd(pgd_val(swapper_pg_dir[KERNBASE >> PGDIR_SHIFT]) + kern_phys);
+ if (boot_cpu_data.x86_capability & X86_FEATURE_PSE) {
+ unsigned long __pe;
+ extern void set_in_cr4(unsigned long);
+
+# define X86_CR4_PSE 0x0010 /* enable page size extensions */
+# define X86_CR4_PGE 0x0080 /* enable global pages */
+ set_in_cr4(X86_CR4_PSE);
+ __pe = _KERNPG_TABLE + _PAGE_4M + kern_phys;
+ if (boot_cpu_data.x86_capability & X86_FEATURE_PGE) {
+ set_in_cr4(X86_CR4_PGE);
+ __pe += _PAGE_GLOBAL;
+ }
+ kern_pgd = __pgd(__pe);
+ kern_pgd_after = kern_pgd;
+ } else {
+ pte_t *pg_table;
+ unsigned long tmp;
+
+ memory_start = PAGE_ALIGN(memory_start);
+ kern_pg0 = memory_start - KERNBASE;
+ pg_table = (pte_t *)memory_start;
+ memory_start += PAGE_SIZE;
+ kern_pgd = __pgd(_PAGE_TABLE | kern_pg0);
+ kern_pgd_after = __pgd(_PAGE_TABLE | (kern_pg0 + kern_phys));
+ for (tmp = 0; tmp < PTRS_PER_PTE; tmp++, pg_table++) {
+ pte_t pte;
+ pte_val(pte) = kern_phys + pgprot_val(PAGE_KERNEL);
+ set_pte(pg_table, pte);
+ kern_phys += PAGE_SIZE;
+ }
+ }
+ btfixup();
+ move_kernel(kern_pgd, (memory_start - KERNBASE - 0x100000 + 4) / 4,
+ kern_phys, kern_pgd_after);
}

- memory_end += PAGE_OFFSET;
+ init_task.tss.cr3 -= page_offset;
+ memory_end += page_offset;
*memory_start_p = memory_start;
*memory_end_p = memory_end;
-
+
#ifdef CONFIG_BLK_DEV_INITRD
if (LOADER_TYPE) {
- initrd_start = INITRD_START ? INITRD_START + PAGE_OFFSET : 0;
+ initrd_start = INITRD_START ? INITRD_START + page_offset : 0;
initrd_end = initrd_start+INITRD_SIZE;
if (initrd_end > memory_end) {
printk("initrd extends beyond end of memory "
--- linux-2.2.0-pre3/arch/i386/kernel/head.S.jj Wed Sep 9 17:56:58 1998
+++ linux-2.2.0-pre3/arch/i386/kernel/head.S Wed Jan 6 17:41:23 1999
@@ -57,9 +57,9 @@ startup_32:
* be using the global pages.
*
* NOTE! We have to correct for the fact that we're
- * not yet offset PAGE_OFFSET..
+ * not yet offset KERNBASE..
*/
-#define cr4_bits mmu_cr4_features-__PAGE_OFFSET
+#define cr4_bits mmu_cr4_features-KERNBASE
movl %cr4,%eax # Turn on 4Mb pages
orl cr4_bits,%eax
movl %eax,%cr4
@@ -324,6 +324,38 @@ ignore_int:
popl %eax
iret

+/* void move_kernel(pgd_t pgd_before_move, unsigned long count,
+ * unsigned long new_phys_base, pgd_t pgd_after_move);
+ */
+ENTRY(move_kernel)
+ pushl %esi
+ pushl %edi
+ pushl %ecx
+ movl $(1f - KERNBASE), %eax
+ jmp *%eax
+1: movl 16(%esp), %eax
+ movl %eax, swapper_pg_dir+(KERNBASE>>(PGDIR_SHIFT-2))
+ movl %cr3, %eax
+ movl %eax, %cr3
+ movl $0x100000, %esi
+ movl $(KERNBASE+0x100000), %edi
+ movl (20-KERNBASE)(%esp), %ecx
+ cld
+ rep
+ movsl
+ movl 28(%esp), %eax
+ movl %eax, swapper_pg_dir+(KERNBASE>>(PGDIR_SHIFT-2))
+ movl 24(%esp), %esi
+ movl %cr3, %eax
+ addl %esi, %eax
+ movl %eax, %cr3
+ movl $1f, %eax
+ jmp *%eax
+1: popl %ecx
+ popl %edi
+ popl %esi
+ ret
+
/*
* The interrupt descriptor table has room for 256 idt's,
* the global descriptor table is dependent on the number
@@ -357,11 +389,11 @@ SYMBOL_NAME(gdt):
.org 0x1000
ENTRY(swapper_pg_dir)
.long 0x00102007
- .fill __USER_PGD_PTRS-1,4,0
- /* default: 767 entries */
+ /* default: 959 entries */
+ .fill (KERNBASE>>PGDIR_SHIFT)-1,4,0
.long 0x00102007
- /* default: 255 entries */
- .fill __KERNEL_PGD_PTRS-1,4,0
+ /* default: 63 entries */
+ .fill (PTRS_PER_PGD-(KERNBASE>>PGDIR_SHIFT))-1,4,0

/*
* The page tables are initialized to only 4MB here - the final page
--- linux-2.2.0-pre3/arch/i386/kernel/i386_ksyms.c.jj Tue Dec 29 20:18:18 1998
+++ linux-2.2.0-pre3/arch/i386/kernel/i386_ksyms.c Tue Jan 5 18:43:40 1999
@@ -69,6 +69,11 @@ EXPORT_SYMBOL(__generic_copy_from_user);
EXPORT_SYMBOL(__generic_copy_to_user);
EXPORT_SYMBOL(strlen_user);

+EXPORT_SYMBOL_NOVERS(BTFIXUP_EXP_INT_INIT(PAGE_OFFSET,0xF0000000));
+#ifdef CONFIG_BINFMT_ELF_MODULE
+EXPORT_SYMBOL_NOVERS(BTFIXUP_EXP_INT_INIT(ELF_ET_DYN_BASE,0xA0000000));
+#endif
+
#ifdef __SMP__
EXPORT_SYMBOL(cpu_data);
EXPORT_SYMBOL(kernel_flag);
--- linux-2.2.0-pre3/arch/i386/kernel/trampoline.S.jj Wed May 6 20:42:54 1998
+++ linux-2.2.0-pre3/arch/i386/kernel/trampoline.S Sat Jan 2 12:10:46 1999
@@ -63,7 +63,7 @@ idt_48:

gdt_48:
.word 0x0800 # gdt limit = 2048, 256 GDT entries
- .long gdt_table-__PAGE_OFFSET # gdt base = gdt (first SMP CPU)
+ .long gdt_table-KERNBASE # gdt base = gdt (first SMP CPU)

.globl SYMBOL_NAME(trampoline_end)
SYMBOL_NAME_LABEL(trampoline_end)
--- linux-2.2.0-pre3/arch/i386/kernel/process.c.jj Mon Dec 28 07:45:13 1998
+++ linux-2.2.0-pre3/arch/i386/kernel/process.c Sat Jan 2 12:10:46 1999
@@ -268,6 +268,7 @@ static inline void kb_wait(void)

void machine_restart(char * __unused)
{
+ int kernel_pgds;
#if __SMP__
/*
* turn off the IO-APIC, so we can do a clean reboot
@@ -309,9 +310,13 @@ void machine_restart(char * __unused)
/* Remap the kernel at virtual address zero, as well as offset zero
from the kernel segment. This assumes the kernel segment starts at
virtual address PAGE_OFFSET. */
+
+ kernel_pgds = KERNEL_PGD_PTRS;
+ if (kernel_pgds > USER_PGD_PTRS)
+ kernel_pgds = USER_PGD_PTRS; /* Cannot copy too much. */

memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
- sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS);
+ sizeof (swapper_pg_dir [0]) * kernel_pgds);

/* Make sure the first page is mapped to the start of physical memory.
It is normally not mapped, to trap kernel NULL pointer dereferences. */
--- linux-2.2.0-pre3/arch/i386/vmlinux.lds.jj Mon Dec 28 07:45:13 1998
+++ linux-2.2.0-pre3/arch/i386/vmlinux.lds Sat Jan 2 12:10:46 1999
@@ -6,7 +6,7 @@ OUTPUT_ARCH(i386)
ENTRY(_start)
SECTIONS
{
- . = 0xC0000000 + 0x100000;
+ . = 0xF0000000 + 0x100000;
_text = .; /* Text and read-only data */
.text : {
*(.text)
--- linux-2.2.0-pre3/arch/i386/Makefile.jj Wed Dec 30 23:17:25 1998
+++ linux-2.2.0-pre3/arch/i386/Makefile Sat Jan 2 12:10:46 1999
@@ -18,6 +18,7 @@ CPP=$(CC) -E
OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
LDFLAGS=-e stext
LINKFLAGS =-T $(TOPDIR)/arch/i386/vmlinux.lds $(LDFLAGS)
+USE_VMLINUX_O=1

CFLAGS_PIPE := -pipe
CFLAGS_NSR := -fno-strength-reduce
@@ -62,6 +63,13 @@ arch/i386/mm: dummy

MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot

+vmlinux: vmlinux.o arch/i386/boot/btfix.o
+ $(LD) $(LINKFLAGS) -o vmlinux vmlinux.o arch/i386/boot/btfix.o
+ $(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
+
+arch/i386/boot/btfix.o: vmlinux.o
+ $(MAKEBOOT) btfix.o
+
zImage: vmlinux
@$(MAKEBOOT) zImage

@@ -87,6 +95,7 @@ install: vmlinux

archclean:
@$(MAKEBOOT) clean
+ rm -f vmlinux.o

archmrproper:

--- linux-2.2.0-pre3/arch/sparc/boot/Makefile.jj Tue Oct 27 18:52:20 1998
+++ linux-2.2.0-pre3/arch/sparc/boot/Makefile Sat Jan 2 12:10:46 1999
@@ -22,19 +22,8 @@ btfixupprep: btfixupprep.c
clean:
rm -f btfixupprep piggyback tftpboot.img btfix.o btfix.s

-BTOBJS := $(HEAD) init/main.o init/version.o \
- $(CORE_FILES_NO_BTFIX) $(FILESYSTEMS) \
- $(NETWORKS) $(DRIVERS)
-
-# I wanted to make this depend upon BTOBJS so that a parallel
-# build would work, but this fails because $(HEAD) cannot work
-# properly as it will cause head.o to be built with the implicit
-# rules not the ones in kernel/Makefile. Someone please fix. --DaveM
-vmlinux.o: dummy
- $(LD) -r $(patsubst %,$(TOPDIR)/%,$(BTOBJS)) $(LIBS) -o vmlinux.o
-
-btfix.s: btfixupprep vmlinux.o
- $(OBJDUMP) -x vmlinux.o | ./btfixupprep > btfix.s
+btfix.s: btfixupprep $(TOPDIR)/vmlinux.o
+ $(OBJDUMP) -x $(TOPDIR)/vmlinux.o | ./btfixupprep > btfix.s

btfix.o: btfix.s
$(CC) -c -o btfix.o btfix.s
--- linux-2.2.0-pre3/arch/sparc/Makefile.jj Sun Oct 4 19:22:42 1998
+++ linux-2.2.0-pre3/arch/sparc/Makefile Sat Jan 2 12:10:46 1999
@@ -32,6 +32,7 @@ endif

#LINKFLAGS = -N -Ttext 0xf0004000
LINKFLAGS = -T arch/sparc/vmlinux.lds
+USE_VMLINUX_O = 1

HEAD := arch/sparc/kernel/head.o arch/sparc/kernel/init_task.o

@@ -54,8 +55,10 @@ endif

# This one has to come last
SUBDIRS += arch/sparc/boot
-CORE_FILES_NO_BTFIX := $(CORE_FILES)
-CORE_FILES += arch/sparc/boot/btfix.o
+
+vmlinux: vmlinux.o arch/sparc/boot/btfix.o
+ $(LD) $(LINKFLAGS) -o vmlinux vmlinux.o arch/sparc/boot/btfix.o
+ $(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map

archclean:
rm -f $(TOPDIR)/vmlinux.aout
--- linux-2.2.0-pre3/Makefile.jj Fri Jan 1 21:49:05 1999
+++ linux-2.2.0-pre3/Makefile Sat Jan 2 12:11:27 1999
@@ -199,6 +199,18 @@ Version: dummy
boot: vmlinux
@$(MAKE) -C arch/$(ARCH)/boot

+ifdef USE_VMLINUX_O
+vmlinux.o: $(CONFIGURATION) init/main.o init/version.o linuxsubdirs
+ $(LD) -r $(HEAD) init/main.o init/version.o \
+ --start-group \
+ $(CORE_FILES) \
+ $(FILESYSTEMS) \
+ $(NETWORKS) \
+ $(DRIVERS) \
+ $(LIBS) \
+ --end-group \
+ -o vmlinux.o
+else
vmlinux: $(CONFIGURATION) init/main.o init/version.o linuxsubdirs
$(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o \
--start-group \
@@ -210,6 +222,7 @@ vmlinux: $(CONFIGURATION) init/main.o in
--end-group \
-o vmlinux
$(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aU] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
+endif

symlinks:
rm -f include/asm

Cheers,
Jakub
___________________________________________________________________
Jakub Jelinek | jj@sunsite.mff.cuni.cz | http://sunsite.mff.cuni.cz
Administrator of SunSITE Czech Republic, MFF, Charles University
___________________________________________________________________
UltraLinux | http://ultra.linux.cz/ | http://ultra.penguin.cz/
Linux version 2.2.0-pre4 on a sparc64 machine (3958.37 BogoMips)
___________________________________________________________________

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/