]> git.neil.brown.name Git - history.git/commitdiff
Import 2.1.35 2.1.35
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:13:06 +0000 (15:13 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:13:06 +0000 (15:13 -0500)
57 files changed:
CREDITS
Documentation/Changes
Documentation/Configure.help
Documentation/ide.txt
Makefile
arch/alpha/config.in
arch/alpha/defconfig
arch/alpha/kernel/alpha_ksyms.c
arch/alpha/kernel/entry.S
arch/alpha/kernel/head.S
arch/alpha/kernel/irq.c
arch/alpha/kernel/process.c
arch/alpha/kernel/setup.c
arch/alpha/kernel/time.c
arch/i386/Makefile
arch/i386/boot/Makefile
arch/i386/boot/bootsect.S
arch/i386/boot/compressed/Makefile
arch/i386/boot/compressed/misc.c
arch/i386/boot/compressed/piggyback.c [deleted file]
arch/i386/boot/compressed/xtract.c [deleted file]
arch/i386/boot/setup.S
arch/i386/boot/tools/build.c
arch/i386/kernel/bios32.c
arch/i386/kernel/head.S
arch/i386/kernel/irq.c
arch/i386/kernel/irq.h [new file with mode: 0644]
arch/i386/kernel/mca.c
arch/i386/kernel/setup.c
arch/i386/kernel/smp.c
arch/i386/kernel/time.c
arch/i386/kernel/traps.c
arch/i386/mm/init.c
arch/i386/vmlinux.lds [new file with mode: 0644]
drivers/char/rtc.c
drivers/net/de4x5.c.lock~ [deleted file]
fs/inode.c
include/asm-alpha/atomic.h
include/asm-alpha/errno.h
include/asm-alpha/init.h [new file with mode: 0644]
include/asm-alpha/irq.h
include/asm-alpha/semaphore.h
include/asm-alpha/spinlock.h
include/asm-i386/boot.h [new file with mode: 0644]
include/asm-i386/init.h [new file with mode: 0644]
include/asm-i386/irq.h
include/asm-m68k/init.h [new file with mode: 0644]
include/asm-mips/init.h [new file with mode: 0644]
include/asm-ppc/init.h [new file with mode: 0644]
include/linux/config.h
include/linux/linkage.h
include/linux/sched.h
include/linux/sunrpc/clnt.h
include/linux/timex.h
init/main.c
kernel/sched.c
net/sunrpc/pmap_clnt.c

diff --git a/CREDITS b/CREDITS
index 5089e3c8035694b3c0d47006934c3cabf1c62a41..d94810c40d832daa0e4c2fc6fa803ad5cb3605b9 100644 (file)
--- a/CREDITS
+++ b/CREDITS
@@ -905,8 +905,9 @@ S: Australia
 
 N: Martin Mares
 E: mj@k332.feld.cvut.cz
+W: http://atrey.karlin.mff.cuni.cz/~mj/
 D: BIOS video mode handling code
-D: Miscellaneous kernel fixes
+D: Miscellaneous kernel fixes and hacks
 D: MOXA C-218 serial board driver
 D: BOOTP support
 S: Kankovskeho 1241
index a15e0311bd9b43c1acc2f251ebc43f4dda99f258..70c7854449e092ad5231d653751ff4941fbf5fd7 100644 (file)
@@ -26,7 +26,10 @@ HTML-ized shopping list.
 http://www.datanet.hu/generations/linux/Changes2.html is an
 English-language HTML version.
 
-Last updated: April 1, 1997.
+   Also, don't forget http://www.linuxhq.com/ for all your Linux kernel
+needs.
+
+Last updated: April 15, 1997.
 Current Author: Chris Ricker (gt1355b@prism.gatech.edu).
 
 Current Minimal Requirements
@@ -35,19 +38,19 @@ Current Minimal Requirements
    Upgrade to at *least* these software revisions before thinking you've
 encountered a bug!
 
-- Kernel modules        modutils-2.1.29-970320
+- Kernel modules        modutils-2.1.34
 - Gnu C                 2.7.2.1
 - Binutils              2.7.0.9
 - Linux C Library       5.4.23
 - Dynamic Linker (ld.so) 1.8.5
 - Linux C++ Library     2.7.2.1
 - Procps                1.01
-- Mount                  2.5p
+- Mount                  2.6e
 - Net-tools              1.32-alpha
-- Kbd                    0.91
 - Loadlin                1.6a
 - Sh-utils               1.16
-- Ncpfs                  2.1.1
+- Autofs                 970409
+- NFS                    0.4.21
 
 Upgrade notes
 *************
@@ -78,20 +81,22 @@ release.
 
    If you upgrade to libc-5.4.x, you also have to upgrade your dynamic
 linker (ld.so) to at least 1.8.5, or all sorts of weirdness will
-happen.  Actually, ld.so-1.8.2 and later will work, but only 1.8.5 is
-widely available, so if you need to upgrade, use it.
+happen.  Actually, ld.so-1.8.2 and later will work, but 1.8.5 is widely
+available, so if you need to upgrade, use it.  If you get a release
+later than 1.8.5, avoid 1.8.10 as it introduces a few bugs that are
+fixed in later releases.
 
 Modules
 =======
 
-   You need to upgrade to modutils-2.1.29-970320 for kernels 2.1.29 and
-later.
+   You need to upgrade to modutils-2.1.34 for kernels 2.1.34 and later.
 
 Binutils
 ========
 
    If you upgrade binutils, please read its accompanying release notes
-to find out the proper way to upgrade it.
+to find out the proper way to upgrade it.  No, the instruction to "rm
+`which encaps`" is not a joke.
 
 Gnu C
 =====
@@ -126,6 +131,15 @@ presence.
    To run bootpd, you'll need to issue the following command:   echo 1
 >/proc/sys/net/ipv4/ip_boot_agent
 
+Mount and network file systems
+==============================
+
+   The NFS code in the kernel is currently being revised, resulting in
+much-improved performance.  As a result, you'll need to upgrade mount
+to a 2.6 release.  Also, amd is being phased out in favor of the much
+better autofs.  You'll also have to get the appropriate utils to use
+autofs as well as the new NFS utils.
+
 RPM
 ===
 
@@ -151,6 +165,16 @@ Sh-utils
 updated to be POSIX-compliant.  As a result, your expr needs to be
 updated.  Use sh-utils 1.16 or later.
 
+Parallel Ports
+==============
+
+   As of 2.1.33, parallel port support can now by handled by the parport
+driver.  Be aware that with Plug-and-Play support turned on, your
+parallel port may no longer be where you expect it; for example, LPT1
+(under DOS) was sometimes /dev/lp1 in Linux, but will probably be
+/dev/lp0 with the new Plug-and-Play driver.  If printing breaks with
+the new driver, try checking your lpd configuration.
+
 How to know the version of the installed programs
 *************************************************
 
@@ -223,8 +247,9 @@ ftp://sunsite.unc.edu/pub/Linux/GCC/ld.so-1.8.5.tar.gz
 Modules utilities
 =================
 
-The 2.1.29-970320 release:
-ftp://ftp.redhat.com/pub/alphabits/modutils-2.1.29-970320.tar.gz
+The 2.1.34 release:
+ftp://ftp.redhat.com/pub/alphabits/modutils-2.1.34.tar.gz
+ftp://ftp.kernel.org/pub/linux/kernel/modutils-2.1.34.tar.gz
 
 Procps utilities
 ================
@@ -263,10 +288,29 @@ ftp://elserv.ffm.fgan.de/pub/linux/loadlin-1.6/update-1.6a/loadlin.exe.gz
 Sh-utils
 ========
 
-The 1.16 release
+The 1.16 release:
 ftp://sunsite.unc.edu/pub/gnu/sh-utils-1.16.tar.gz
 ftp://prep.ai.mit.edu/pub/gnu/sh-utils-1.16.tar.gz
 
+Mount
+=====
+
+The 2.6e release:
+ftp://ftp.win.tue.nl/pub/linux/util/mount-2.6e.tar.gz
+
+Autofs
+======
+
+The 970409 release:
+ftp://ftp.kernel.org/pub/linux/daemons/autofs/autofs-970409.tar.gz
+
+NFS
+===
+
+The 0.4.21 release:
+ftp://ftp.mathematik.th-darmstadt.de/pub/linux/okir/linux-nfs-0.4.21.tar.gz
+ftp://linux.nrao.edu/pub/people/okir/linux-nfs-0.4.21.tar.gz
+
 Other Info
 ==========
 
index dc3f6b1df239f3964b6f66ab7d5941a9339c6622..a024a3c81f810b0d7d6d33cdc772cc80a41928cd 100644 (file)
@@ -4439,6 +4439,12 @@ CONFIG_RTC
   have a use for such a device (such as periodic data sampling), then
   say Y here, and go read the file Documentation/rtc.txt for details.
 
+ARC console time
+CONFIG_RTC_ARC
+  If you boot your Alpha using the ARC firmware, say Y here. This option
+  adjusts the RTC clock to take into account the different starting epoch
+  used by ARC.
+
 Sound card support
 CONFIG_SOUND
   If you have a Sound Card in your Computer, i.e. if it can say more
index 0c93f6d533eff3b04b887ad68c3d87bf8a616195..f9ececdd525c9c5a67f27437059d38519bf10eb3 100644 (file)
@@ -452,10 +452,10 @@ by doing the following after installing slackware (or whatever):
 
        0. Boot from the "boot floppy" created during the installation
         1. Mount your DOS partition as /dos (and stick it in /etc/fstab)
-        2. Move your kernel (/vmlinuz) to /dos/vmlinuz with:  mv /vmlinuz /dos
-        3. Edit /etc/lilo.conf to change /vmlinuz to /dos/vmlinuz
-        4. Move /boot to /dos/boot with:  cp -a /boot /dos ; rm -r /boot
-        5. Create a symlink for LILO to use with:  ln -s /dos/boot /boot
+        2. Move /boot to /dos/boot with:  cp -a /boot /dos ; rm -r /boot
+        3. Create a symlink for LILO to use with:  ln -s /dos/boot /boot
+        4. Move your kernel (/vmlinuz) to /boot/vmlinuz:  mv /vmlinuz /boot
+        5. Edit /etc/lilo.conf to change /vmlinuz to /boot/vmlinuz
         6. Re-run LILO with:  lilo
 
        A danger with this approach is that whenever an MS-DOS "defragmentation"
index 4e578a229791ac0ad3acc16cda4a3115206a94d4..d88d06be329af070b832121a42231ee8c491e290 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 VERSION = 2
 PATCHLEVEL = 1
-SUBLEVEL = 34
+SUBLEVEL = 35
 
 ARCH := $(shell uname -m | sed s/i.86/i386/)
 
index cc523e4eaa5dbafc9447603a75d9ab9ef3b58c10..e62ec31d030a778154f6e8dc7b437a866b4f7d4b 100644 (file)
@@ -151,6 +151,9 @@ endmenu
 source fs/Config.in
 
 source drivers/char/Config.in
+if [ "$CONFIG_RTC" != "n" ]; then
+  bool '  ARC console time' CONFIG_RTC_ARC y
+fi
 
 mainmenu_option next_comment
 comment 'Sound'
index d29eb9918c18e1f682746d109e40a5b93ab52cdd..a6ee5a17c1edff28c014448f5b9cbd8e15df5f3c 100644 (file)
@@ -224,6 +224,7 @@ CONFIG_PSMOUSE=y
 # CONFIG_APM is not set
 # CONFIG_WATCHDOG is not set
 # CONFIG_RTC is not set
+CONFIG_RTC_ARC=y
 
 #
 # Sound
index 32a7bd6dfafb719c4e8b52a1cba5f7bfc8d4e30f..be75f566fa2e7efa52444bc61cf6d2154d3379da 100644 (file)
@@ -19,6 +19,7 @@
 #include <asm/uaccess.h>
 #include <asm/processor.h>
 #include <asm/checksum.h>
+#include <linux/interrupt.h>
 #include <asm/softirq.h>
 
 extern void bcopy (const char *src, char *dst, int len);
@@ -38,6 +39,7 @@ extern void __divqu (void);
 extern void __remqu (void);
 
 EXPORT_SYMBOL(__alpha_bh_counter);
+EXPORT_SYMBOL(local_irq_count);
 
 /* platform dependent support */
 EXPORT_SYMBOL(_inb);
index a796c58f51237ceb7d6421b3c803b2d41ec06435..5926dd25c242eedced1cc1a8c44a5ba58d8be50d 100644 (file)
 .ent   entInt
 entInt:
        SAVE_ALL
-/* start atomic operation with respect to software interrupts */
-       lda     $0,intr_count
-       ldl     $1,0($0)
-       addq    $1,1,$1
-       stl     $1,0($0)
-/* set up the arguments to the C interrupt handler */
        ldq     $8,current_set
        jsr     $26,do_entInt
-/* ok, return */
-       lda     $0,intr_count
-       ldl     $1,0($0)
-       subq    $1,1,$1
-       stl     $1,0($0)
        br      $31,ret_from_sys_call
 .end entInt
 
index d19e829edeef87936336327b8c5e088bee22c77e..17ca4581a112cf92ba5e657cb2839a9232f1b39d 100644 (file)
@@ -24,8 +24,7 @@ __start:
        br      $27,1f
 1:     ldgp    $29,0($27)
        /* We need to get current loaded up with our first task.  */
-       lda     $8,init_task
-       stq     $8,current_set
+       ldq     $8,current_set
        /* And then we can start the kernel.  */
        jsr     $26,start_kernel
        halt
index a747b43b73995f050782e3b6bfaf4f5550aaa82e..133c278281e3ac672ac2ed1d0fffb56bebdb1555 100644 (file)
 #include <asm/bitops.h>
 #include <asm/dma.h>
 
-extern void timer_interrupt(struct pt_regs * regs);
+#define RTC_IRQ    8
+#ifdef CONFIG_RTC
+#define TIMER_IRQ  0        /* timer is the pit */
+#else
+#define TIMER_IRQ  RTC_IRQ  /* the timer is, in fact, the rtc */
+#endif
 
 #if NR_IRQS > 64
 #  error Unable to handle more than 64 irq levels.
@@ -132,6 +137,7 @@ void enable_irq(unsigned int irq_nr)
 /*
  * Initial irq handlers.
  */
+static struct irqaction timer_irq = { NULL, 0, 0, NULL, NULL, NULL};
 static struct irqaction *irq_action[NR_IRQS];
 
 int get_irq_list(char *buf)
@@ -143,7 +149,7 @@ int get_irq_list(char *buf)
                action = irq_action[i];
                if (!action) 
                        continue;
-               len += sprintf(buf+len, "%2d: %8d %c %s",
+               len += sprintf(buf+len, "%2d: %10u %c %s",
                        i, kstat.interrupts[i],
                        (action->flags & SA_INTERRUPT) ? '+' : ' ',
                        action->name);
@@ -211,7 +217,10 @@ int request_irq(unsigned int irq,
                shared = 1;
        }
 
-       action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
+        if (irq == TIMER_IRQ)
+               action = &timer_irq;
+        else
+               action = (struct irqaction *)kmalloc(sizeof(struct irqaction),
                                             GFP_KERNEL);
        if (!action)
                return -ENOMEM;
@@ -329,6 +338,7 @@ static inline void handle_irq(int irq, struct pt_regs * regs)
 static inline void device_interrupt(int irq, int ack, struct pt_regs * regs)
 {
        struct irqaction * action;
+       int cpu = smp_processor_id();
 
        if ((unsigned) irq > NR_IRQS) {
                printk("device_interrupt: unexpected interrupt %d\n", irq);
@@ -660,7 +670,9 @@ int probe_irq_off(unsigned long irqs)
 {
        int i;
        
-       irqs &= irq_mask & ~1;  /* always mask out irq 0---it's the unused timer */
+        /* as irq 0 & 8 handling don't use this function, i didn't
+        * bother changing the following: */
+        irqs &= irq_mask & ~1;  /* always mask out irq 0---it's the unused timer */
 #ifdef CONFIG_ALPHA_P2K
        irqs &= ~(1 << 8);      /* mask out irq 8 since that's the unused RTC input to PIC */
 #endif
@@ -700,7 +712,7 @@ asmlinkage void do_entInt(unsigned long type, unsigned long vector, unsigned lon
                        printk("Interprocessor interrupt? You must be kidding\n");
                        break;
                case 1:
-                       timer_interrupt(&regs);
+                       handle_irq(RTC_IRQ, &regs);
                        return;
                case 2:
                        machine_check(vector, la_ptr, &regs);
index 7bcb8dc9725950fff10d0d4c96e604a6034c679e..f30afa5c96fdf1811ebe7e629f80261a74a5d448 100644 (file)
 #include <linux/elfcore.h>
 #include <linux/reboot.h>
 
+#ifdef CONFIG_RTC
+#include <linux/mc146818rtc.h>
+#endif
+
 #include <asm/reg.h>
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -66,6 +70,24 @@ out:
 
 void machine_restart(char * __unused)
 {
+#ifdef CONFIG_RTC  /* reset rtc to defaults */
+       unsigned char control;
+       unsigned long flags;
+
+       /* i'm not sure if i really need to disable interrupts here */
+       save_flags(flags);
+       cli();
+       /* reset periodic interrupt frequency */
+        CMOS_WRITE(0x26, RTC_FREQ_SELECT);
+
+       /* turn on periodic interrupts */
+       control = CMOS_READ(RTC_CONTROL);
+       control |= RTC_PIE;
+       CMOS_WRITE(control, RTC_CONTROL);       
+        CMOS_READ(RTC_INTR_FLAGS);
+       restore_flags(flags);
+#endif
+
 #if defined(CONFIG_ALPHA_SRM) && defined(CONFIG_ALPHA_ALCOR)
        /* who said DEC engineer's have no sense of humor? ;-)) */
        *(int *) GRU_RESET = 0x0000dead;
index f53d556e321f340ed7bfa6728e165c5476b5133a..0fa1129eee8ab566dca98f5b0630a5d1680120e4 100644 (file)
 #include <linux/delay.h>
 #include <linux/config.h>      /* CONFIG_ALPHA_LCA etc */
 
+#ifdef CONFIG_RTC
+#include <linux/ioport.h>
+#include <linux/timex.h>
+#endif
+
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
@@ -83,9 +88,17 @@ static void init_pit (void)
     outb(0x18, 0x41);
 #endif
 
+#ifdef CONFIG_RTC /* setup interval timer if /dev/rtc is being used */
+    outb(0x34, 0x43);  /* binary, mode 2, LSB/MSB, ch 0 */
+    outb(LATCH & 0xff, 0x40); /* LSB */
+    outb(LATCH >> 8, 0x40); /* MSB */
+    request_region(0x40, 0x20, "timer"); /* reserve pit */
+#else
     outb(0x36, 0x43);  /* counter 0: system timer */
     outb(0x00, 0x40);
     outb(0x00, 0x40);
+    request_region(0x70, 0x10, "timer"); /* reserve rtc */
+#endif
 
     outb(0xb6, 0x43);  /* counter 2: speaker */
     outb(0x31, 0x42);
index 05dc250f19c4ae635d18ed08dd7d1df54ff6a565..b289d4f82f33aca8bd39c1c93ab561166e79c1f1 100644 (file)
@@ -10,6 +10,8 @@
  * 1995-03-26    Markus Kuhn
  *      fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
  *      precision CMOS clock update
+ * 1997-01-09    Adrian Sun
+ *      use interval timer if CONFIG_RTC=y
  */
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/mc146818rtc.h>
 #include <linux/timex.h>
 
-#define TIMER_IRQ 0
+#ifdef CONFIG_RTC 
+#define TIMER_IRQ 0  /* using pit for timer */
+#else 
+#define TIMER_IRQ 8  /* using rtc for timer */
+#endif
 
 extern struct hwrpb_struct *hwrpb;
 
@@ -61,7 +67,7 @@ static inline __u32 rpcc(void)
  * timer_interrupt() needs to keep up the real-time clock,
  * as well as call the "do_timer()" routine every clocktick
  */
-void timer_interrupt(struct pt_regs * regs)
+void timer_interrupt(int irq, void *dev, struct pt_regs * regs)
 {
        __u32 delta, now;
 
@@ -125,6 +131,10 @@ static inline unsigned long mktime(unsigned int year, unsigned int mon,
 
 void time_init(void)
 {
+#ifdef CONFIG_RTC
+       unsigned char save_control;
+#endif
+        void (*irq_handler)(int, void *, struct pt_regs *);
        unsigned int year, mon, day, hour, min, sec;
        int i;
 
@@ -178,6 +188,21 @@ void time_init(void)
        state.scaled_ticks_per_cycle = ((unsigned long) HZ << FIX_SHIFT) / hwrpb->cycle_freq;
        state.max_cycles_per_tick = (2 * hwrpb->cycle_freq) / HZ;
        state.last_rtc_update = 0;
+
+#ifdef CONFIG_RTC 
+       /* turn off RTC interrupts before /dev/rtc is initialized */
+       save_control = CMOS_READ(RTC_CONTROL);
+        save_control &= ~RTC_PIE;
+        save_control &= ~RTC_AIE;
+        save_control &= ~RTC_UIE;
+        CMOS_WRITE(save_control, RTC_CONTROL);
+        CMOS_READ(RTC_INTR_FLAGS);
+#endif
+
+       /* setup timer */ 
+        irq_handler = timer_interrupt;
+        if (request_irq(TIMER_IRQ, irq_handler, 0, "timer", NULL))
+         panic("Could not allocate timer IRQ!");
 }
 
 /*
index 4365311d49063ab9919b734730a9b4477dc49b9f..8bd6d89530a084bdd20ccedd6ac8c9918a45377b 100644 (file)
@@ -17,33 +17,11 @@ AS86    =$(CROSS_COMPILE)as86 -0 -a
 AS386   =$(CROSS_COMPILE)as86 -3
 LD86    =$(CROSS_COMPILE)ld86 -0
 
-#
-# ZIMAGE_OFFSET is the load offset of the compression loader
-# BZIMAGE_OFFSET is the load offset of the high loaded compression loader
-#
-ZIMAGE_OFFSET=0x1000
-BZIMAGE_OFFSET=0x100000
-
-#
-# IMAGE_OFFSET is the load offset of the _real_ kernel, soon
-# to be offset by another 0xC0000000...
-#
-IMAGE_OFFSET=0xC0100000
-
-# This is used for ELF - it needs to migrate or be moved.
-LD_RFLAG = -m elf_i386
-
 LD=$(CROSS_COMPILE)ld -m elf_i386
-CPP=$(CC) -E -D__ELF__
-OBJDUMP=$(CROSS_COMPILE)objdump
-OBJDUMP_FLAGS=-k -q 
-ENCAPS=$(CROSS_COMPILE)encaps
-OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -R .stab -R .stabstr
-ZLDFLAGS=-e startup_32 
+CPP=$(CC) -E
+OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
 LDFLAGS=-e stext
-ZLINKFLAGS =-Ttext $(ZIMAGE_OFFSET) $(ZLDFLAGS)
-BZLINKFLAGS =-Ttext $(BZIMAGE_OFFSET) $(ZLDFLAGS)
-LINKFLAGS =-Ttext $(IMAGE_OFFSET) $(LDFLAGS)
+LINKFLAGS =-T arch/i386/vmlinux.lds $(LDFLAGS)
 
 CFLAGS := $(CFLAGS) -pipe -fno-strength-reduce
 
index 503b0cce6e5fba2a527173e5b5a7614dab15190f..83e4a19dec69da923c05143816e1f0dd60768379 100644 (file)
@@ -8,29 +8,21 @@
 # Copyright (C) 1994 by Linus Torvalds
 #
 
-HOSTCFLAGS := $(HOSTCFLAGS) -D__BFD__
-
 ifdef SMP
 HOSTCFLAGS := $(HOSTCFLAGS) -D__SMP__
 endif
 
+BOOT_INCL =    $(TOPDIR)/include/linux/config.h \
+               $(TOPDIR)/include/linux/autoconf.h \
+               $(TOPDIR)/include/asm/boot.h
+
 zImage: $(CONFIGURE) bootsect setup compressed/vmlinux tools/build
-       if hash $(ENCAPS) 2> /dev/null; then \
-         $(OBJDUMP) $(OBJDUMP_FLAGS) -o $(ZIMAGE_OFFSET) compressed/vmlinux > compressed/vmlinux.out; \
-       else \
-         $(OBJCOPY) compressed/vmlinux compressed/vmlinux.out; \
-       fi
+       $(OBJCOPY) compressed/vmlinux compressed/vmlinux.out
        tools/build bootsect setup compressed/vmlinux.out $(ROOT_DEV) > zImage
-       sync
 
-bzImage: $(CONFIGURE) bbootsect setup compressed/bvmlinux tools/bbuild
-       if hash $(ENCAPS) 2> /dev/null; then \
-         $(OBJDUMP) $(OBJDUMP_FLAGS) -o $(BZIMAGE_OFFSET) compressed/bvmlinux > compressed/bvmlinux.out; \
-       else \
-         $(OBJCOPY) compressed/bvmlinux compressed/bvmlinux.out; \
-       fi
-       tools/bbuild bbootsect setup compressed/bvmlinux.out $(ROOT_DEV) > bzImage
-       sync
+bzImage: $(CONFIGURE) bbootsect bsetup compressed/bvmlinux tools/build
+       $(OBJCOPY) compressed/bvmlinux compressed/bvmlinux.out
+       tools/build -b bbootsect bsetup compressed/bvmlinux.out $(ROOT_DEV) > bzImage
 
 compressed/vmlinux: $(TOPDIR)/vmlinux
        @$(MAKE) -C compressed vmlinux
@@ -54,25 +46,31 @@ install: $(CONFIGURE) zImage
 tools/build: tools/build.c
        $(HOSTCC) $(HOSTCFLAGS) -o $@ $< -I$(TOPDIR)/include
 
-tools/bbuild: tools/build.c
-       $(HOSTCC) $(HOSTCFLAGS) -D__BIG_KERNEL__ -o $@ $< -I$(TOPDIR)/include
-
 setup: setup.o
        $(LD86) -s -o $@ $<
 
 setup.o: setup.s
        $(AS86) -o $@ $<
 
-setup.s: setup.S video.S $(CONFIGURE) $(TOPDIR)/include/linux/config.h Makefile
+setup.s: setup.S video.S Makefile $(BOOT_INCL) $(TOPDIR)/include/linux/version.h
        $(CPP) -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@
 
+bsetup: bsetup.o
+       $(LD86) -s -o $@ $<
+
+bsetup.o: bsetup.s
+       $(AS86) -o $@ $<
+
+bsetup.s: setup.S video.S Makefile $(BOOT_INCL) $(TOPDIR)/include/linux/version.h
+       $(CPP) -D__BIG_KERNEL__ -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@
+
 bootsect: bootsect.o
        $(LD86) -s -o $@ $<
 
 bootsect.o: bootsect.s
        $(AS86) -o $@ $<
 
-bootsect.s: bootsect.S $(CONFIGURE) $(TOPDIR)/include/linux/config.h Makefile
+bootsect.s: bootsect.S Makefile $(BOOT_INCL)
        $(CPP) -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@
 
 bbootsect: bbootsect.o
@@ -81,14 +79,13 @@ bbootsect: bbootsect.o
 bbootsect.o: bbootsect.s
        $(AS86) -o $@ $<
 
-bbootsect.s: bootsect.S $(CONFIGURE) $(TOPDIR)/include/linux/config.h Makefile
+bbootsect.s: bootsect.S Makefile $(BOOT_INCL)
        $(CPP) -D__BIG_KERNEL__ -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@
 
 dep:
 
 clean:
-       rm -f bootsect setup
-       rm -f bbootsect
-       rm -f zImage tools/build compressed/vmlinux.out
-       rm -f bzImage tools/bbuild compressed/bvmlinux.out
+       rm -f tools/build
+       rm -f setup bootsect zImage compressed/vmlinux.out
+       rm -f bsetup bbootsect bzImage compressed/bvmlinux.out
        @$(MAKE) -C compressed clean
index 88a04190dd44ab57a07e98b58a0328a743f933a0..1f06031af6b99b6a24895325b4c001a0b4571d42 100644 (file)
@@ -1,11 +1,4 @@
 !
-! SYS_SIZE is the number of clicks (16 bytes) to be loaded.
-! 0x7F00 is 0x7F000 bytes = 508kB, more than enough for current
-! versions of linux which compress the kernel
-!
-#include <linux/config.h>
-SYSSIZE = DEF_SYSSIZE
-!
 !      bootsect.s              Copyright (C) 1991, 1992 Linus Torvalds
 !      modified by Drew Eckhardt
 !      modified by Bruce Evans (bde)
@@ -29,13 +22,17 @@ SYSSIZE = DEF_SYSSIZE
 ! read errors will result in a unbreakable loop. Reboot by hand. It
 ! loads pretty fast by getting whole tracks at a time whenever possible.
 
+#include <asm/boot.h>
+
 .text
 
-SETUPSECS = 4                          ! nr of setup-sectors
+SETUPSECS = 4                          ! default nr of setup-sectors
 BOOTSEG   = 0x07C0                     ! original address of boot-sector
 INITSEG   = DEF_INITSEG                        ! we move boot here - out of the way
 SETUPSEG  = DEF_SETUPSEG               ! setup starts here
 SYSSEG    = DEF_SYSSEG                 ! system loaded at 0x10000 (65536).
+SYSSIZE          = DEF_SYSSIZE                 ! system size: number of 16-byte clicks
+                                       ! to be loaded
 
 ! ROOT_DEV & SWAP_DEV are now written by "build".
 ROOT_DEV = 0
index d7f093e3f14ee8a591ebdcc4e9339fc7f8d500ae..9a78bca69d5082751bf595ef1611407dea10b1db 100644 (file)
@@ -10,15 +10,22 @@ SYSTEM = $(TOPDIR)/vmlinux
 OBJECTS = $(HEAD) misc.o
 
 CFLAGS = -O2 -DSTDC_HEADERS
+ZLDFLAGS = -e startup_32
+
+#
+# ZIMAGE_OFFSET is the load offset of the compression loader
+# BZIMAGE_OFFSET is the load offset of the high loaded compression loader
+#
+ZIMAGE_OFFSET = 0x1000
+BZIMAGE_OFFSET = 0x100000
+
+ZLINKFLAGS = -Ttext $(ZIMAGE_OFFSET) $(ZLDFLAGS)
+BZLINKFLAGS = -Ttext $(BZIMAGE_OFFSET) $(ZLDFLAGS)
 
 ifdef SMP
 CFLAGS := $(CFLAGS) -D__SMP__
 endif
 
-TARGET=--target elf32-i386
-INPUT_DATA=input_data
-INPUT_LEN=input_len
-
 all: vmlinux
 
 vmlinux: piggy.o $(OBJECTS)
@@ -40,24 +47,14 @@ head.o: head.S $(TOPDIR)/include/linux/tasks.h
 endif
 
 
-# You cannot compress a file and have the kernel uncompress it, it must
-# be stdin
 piggy.o:       $(SYSTEM)
        tmppiggy=/tmp/$$$$piggy; \
        rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk; \
-       if hash $(ENCAPS) 2> /dev/null; then \
-         $(OBJDUMP) $(OBJDUMP_FLAGS) -o $(IMAGE_OFFSET) $(SYSTEM) > $$tmppiggy; \
-       else \
-         $(OBJCOPY) $(SYSTEM) $$tmppiggy; \
-       fi; \
+       $(OBJCOPY) $(SYSTEM) $$tmppiggy; \
        gzip -f -9 < $$tmppiggy > $$tmppiggy.gz; \
-       if hash $(ENCAPS) 2> /dev/null; then \
-         $(ENCAPS) $(TARGET) piggy.o $$tmppiggy.gz $(INPUT_DATA) $(INPUT_LEN); \
-       else \
-         echo "SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}" > $$tmppiggy.lnk; \
-         $(LD) -m elf_i386 -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-i386 -T $$tmppiggy.lnk; \
-       fi; \
+       echo "SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}" > $$tmppiggy.lnk; \
+       $(LD) -m elf_i386 -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-i386 -T $$tmppiggy.lnk; \
        rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk
 
 clean:
-       rm -f xtract piggyback vmlinux bvmlinux
+       rm -f vmlinux bvmlinux
index b77b4f03e8be9e9da7e77cb29d802f561d6bbf55..fd835f5c0dffb43fefc92f35c865a745ceca4b1f 100644 (file)
@@ -75,11 +75,7 @@ static void gzip_release(void **);
  * This is set up by the setup-routine at boot-time
  */
 #define EXT_MEM_K (*(unsigned short *)0x90002)
-#define DRIVE_INFO (*(struct drive_info *)0x90080)
 #define SCREEN_INFO (*(struct screen_info *)0x90000)
-#define RAMDISK_SIZE (*(unsigned short *)0x901F8)
-#define ORIG_ROOT_DEV (*(unsigned short *)0x901FC)
-#define AUX_DEVICE_INFO (*(unsigned char *)0x901FF)
 
 extern char input_data[];
 extern int input_len;
diff --git a/arch/i386/boot/compressed/piggyback.c b/arch/i386/boot/compressed/piggyback.c
deleted file mode 100644 (file)
index 4028411..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- *     linux/zBoot/piggyback.c
- *
- *     (C) 1993 Hannu Savolainen
- */
-
-/*
- *     This program reads the compressed system image from stdin and
- *     encapsulates it into an object file written to the stdout.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <a.out.h>
-
-int main(int argc, char *argv[])
-{
-       int c, n=0, len=0;
-       char tmp_buf[512*1024];
-       
-       struct exec obj = {0x00640107}; /* object header */
-       char string_names[] = {"_input_data\0_input_len\0"};
-
-       struct nlist var_names[2] = /* Symbol table */
-               {       
-                       {       /* _input_data  */
-                               (char *)4, 7, 0, 0, 0
-                       },
-                       {       /* _input_len */
-                               (char *)16, 7, 0, 0, 0
-                       }
-               };
-
-
-       len = 0;
-       while ((n = read(0, &tmp_buf[len], sizeof(tmp_buf)-len+1)) > 0)
-             len += n;
-
-       if (n==-1)
-       {
-               perror("stdin");
-               exit(-1);
-       }
-
-       if (len >= sizeof(tmp_buf))
-       {
-               fprintf(stderr, "%s: Input too large\n", argv[0]);
-               exit(-1);
-       }
-
-       fprintf(stderr, "Compressed size %d.\n", len);
-
-/*
- *     Output object header
- */
-       obj.a_data = len + sizeof(long);
-       obj.a_syms = sizeof(var_names);
-       write(1, (char *)&obj, sizeof(obj));
-
-/*
- *     Output data segment (compressed system & len)
- */
-       write(1, tmp_buf, len);
-       write(1, (char *)&len, sizeof(len));
-
-/*
- *     Output symbol table
- */
-       var_names[1].n_value = len;
-       write(1, (char *)&var_names, sizeof(var_names));
-
-/*
- *     Output string table
- */
-       len = sizeof(string_names) + sizeof(len);
-       write(1, (char *)&len, sizeof(len));
-       write(1, string_names, sizeof(string_names));
-
-       exit(0);
-
-}
diff --git a/arch/i386/boot/compressed/xtract.c b/arch/i386/boot/compressed/xtract.c
deleted file mode 100644 (file)
index 91de49c..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  linux/zBoot/xtract.c
- *
- *  Copyright (C) 1993  Hannu Savolainen
- *
- *     Extracts the system image and writes it to the stdout.
- *     based on tools/build.c by Linus Torvalds
- */
-
-#include <stdio.h>     /* fprintf */
-#include <string.h>
-#include <stdlib.h>    /* contains exit */
-#include <sys/types.h> /* unistd.h needs this */
-#include <sys/stat.h>
-#include <sys/sysmacros.h>
-#include <unistd.h>    /* contains read/write */
-#include <fcntl.h>
-#include <a.out.h>
-
-#define N_MAGIC_OFFSET 1024
-
-static int GCC_HEADER = sizeof(struct exec);
-
-#define STRINGIFY(x) #x
-
-void die(char * str)
-{
-       fprintf(stderr,"%s\n",str);
-       exit(1);
-}
-
-void usage(void)
-{
-       die("Usage: xtract system [ | gzip | piggyback > piggy.s]");
-}
-
-int main(int argc, char ** argv)
-{
-       int i,c,id, sz;
-       char buf[1024];
-       char major_root, minor_root;
-       struct stat sb;
-
-       struct exec *ex = (struct exec *)buf;
-
-       if (argc  != 2)
-               usage();
-       
-       if ((id=open(argv[1],O_RDONLY,0))<0)
-               die("Unable to open 'system'");
-       if (read(id,buf,GCC_HEADER) != GCC_HEADER)
-               die("Unable to read header of 'system'");
-       if (N_MAGIC(*ex) == ZMAGIC) {
-               GCC_HEADER = N_MAGIC_OFFSET;
-               lseek(id, GCC_HEADER, SEEK_SET);
-       } else if (N_MAGIC(*ex) != QMAGIC)
-               die("Non-GCC header of 'system'");
-
-       sz = N_SYMOFF(*ex) - GCC_HEADER + 4;    /* +4 to get the same result than tools/build */
-
-       fprintf(stderr, "System size is %d\n", sz);
-
-       while (sz)
-       {
-               int l, n;
-
-               l = sz;
-               if (l > sizeof(buf)) l = sizeof(buf);
-
-               if ((n=read(id, buf, l)) !=l)
-               {
-                       if (n == -1) 
-                          perror(argv[1]);
-                       else
-                          fprintf(stderr, "Unexpected EOF\n");
-
-                       die("Can't read system");
-               }
-
-               write(1, buf, l);
-               sz -= l;
-       }
-
-       close(id);
-       return(0);
-}
index 5cb68b91091ec2f3b5284c2ae23a9ae9498830f3..32d852efceb81e35940c8119d7b2e234bde66a82 100644 (file)
 ! Video handling moved to video.S by Martin Mares, March 1996
 ! <mj@k332.feld.cvut.cz>
 
-! NOTE! These had better be the same as in bootsect.s!
 #define __ASSEMBLY__
 #include <linux/config.h>
 #include <asm/segment.h>
 #include <linux/version.h>
 #include <linux/compile.h>
+#include <asm/boot.h>
 
 ! Signature words to ensure LILO loaded us right
 #define SIG1   0xAA55
@@ -79,23 +79,32 @@ type_of_loader:     .byte   0               ! = 0, old one (LILO, Loadlin,
                                        !       T=3 for SYSLX
                                        !       T=4 for ETHERBOOT
                                        !       V = version
-loadflags:     .byte   0       ! unused bits =0 (reserved for future development)
+loadflags:                     ! flags, unused bits must be zero (RFU)
 LOADED_HIGH    = 1             ! bit within loadflags,
                                ! if set, then the kernel is loaded high
 CAN_USE_HEAP   = 0x80          ! if set, the loader also has set heap_end_ptr
                                ! to tell how much space behind setup.S
                                | can be used for heap purposes.
                                ! Only the loader knows what is free!
+#ifndef __BIG_KERNEL__
+               .byte   0x00
+#else
+               .byte   LOADED_HIGH
+#endif
+
 setup_move_size: .word  0x8000 ! size to move, when we (setup) are not
                                ! loaded at 0x90000. We will move ourselves
                                ! to 0x90000 then just before jumping into
                                ! the kernel. However, only the loader
                                ! know how much of data behind us also needs
                                ! to be loaded.
-code32_start:  .long   0x1000          ! here loaders can put a different
+code32_start:                          ! here loaders can put a different
                                        ! start address for 32-bit code.
-                                       !   0x1000 = default for zImage
-                                       ! 0x100000 = default for big kernel
+#ifndef __BIG_KERNEL__
+               .long   0x1000          !   0x1000 = default for zImage
+#else
+               .long   0x100000        ! 0x100000 = default for big kernel
+#endif
 ramdisk_image: .long   0       ! address of loaded ramdisk image
                                ! Here the loader (or kernel generator) puts
                                ! the 32-bit address were it loaded the image.
index a7e9d063fef73b092f6258f0aca8361be8c1439f..039f2700326af48c6affb8d2a1ba211653c462d4 100644 (file)
@@ -1,7 +1,8 @@
 /*
- *  linux/tools/build.c
+ *  arch/i386/boot/tools/build.c
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  Copyright (C) 1997 Martin Mares
  */
 
 /*
  * Changes by tytso to allow root device specification
  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
  * Cross compiling fixes by Gertjan van Wingerde, July 1996
+ * Rewritten by Martin Mares, April 1997
  */
 
-#include <stdio.h>     /* fprintf */
+#include <stdio.h>
 #include <string.h>
-#include <stdlib.h>    /* contains exit */
-#include <sys/types.h> /* unistd.h needs this */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/sysmacros.h>
-#include <unistd.h>    /* contains read/write */
+#include <unistd.h>
 #include <fcntl.h>
-#include <linux/a.out.h>
 #include <linux/config.h>
-#include <errno.h>
+#include <asm/boot.h>
 
-#define MINIX_HEADER 32
-
-#define N_MAGIC_OFFSET 1024
-#ifndef __BFD__
-static int GCC_HEADER = sizeof(struct exec);
-#endif
-
-#ifdef __BIG_KERNEL__
-#define SYS_SIZE 0xffff
-#else
-#define SYS_SIZE DEF_SYSSIZE
-#endif
+typedef unsigned char byte;
+typedef unsigned short word;
+typedef unsigned long u32;
 
 #define DEFAULT_MAJOR_ROOT 0
 #define DEFAULT_MINOR_ROOT 0
 
-/* max nr of sectors of setup: don't change unless you also change
- * bootsect etc */
+/* Minimal number of setup sectors (see also bootsect.S) */
 #define SETUP_SECTS 4
 
-#define STRINGIFY(x) #x
-
-typedef union {
-       int i;
-       long l;
-       short s[2];
-       char b[4];
-} conv;
+byte buf[1024];
+int fd;
+int is_big_kernel;
 
-long intel_long(long l)
+void die(const char * str, ...)
 {
-       conv t;
-
-       t.b[0] = l & 0xff; l >>= 8;
-       t.b[1] = l & 0xff; l >>= 8;
-       t.b[2] = l & 0xff; l >>= 8;
-       t.b[3] = l & 0xff; l >>= 8;
-       return t.l;
-}
-
-int intel_int(int i)
-{
-       conv t;
-
-       t.b[0] = i & 0xff; i >>= 8;
-        t.b[1] = i & 0xff; i >>= 8;
-        t.b[2] = i & 0xff; i >>= 8;
-        t.b[3] = i & 0xff; i >>= 8;
-        return t.i;
+       va_list args;
+       va_start(args, str);
+       vfprintf(stderr, str, args);
+       fputc('\n', stderr);
+       exit(1);
 }
 
-short intel_short(short l)
-{
-       conv t;
+/* Reading of ld86 output (Minix format) */
 
-       t.b[0] = l & 0xff; l >>= 8;
-       t.b[1] = l & 0xff; l >>= 8;
-       return t.s[0];
-}
+#define MINIX_HEADER_LEN 32
 
-void die(const char * str)
+int minix_open(const char *name)
 {
-       fprintf(stderr,"%s\n",str);
-       exit(1);
+       static byte hdr[] = { 0x01, 0x03, 0x10, 0x04, 0x20, 0x00, 0x00, 0x00 };
+       static u32 *lb = (u32 *) buf;
+
+       if ((fd = open(name, O_RDONLY, 0)) < 0)
+               die("Unable to open `%s': %m", name);
+       if (read(fd, buf, MINIX_HEADER_LEN) != MINIX_HEADER_LEN)
+               die("%s: Unable to read header", name);
+       if (memcmp(buf, hdr, sizeof(hdr)) || lb[5])
+               die("%s: Non-Minix header", name);
+       if (lb[3])
+               die("%s: Illegal data segment");
+       if (lb[4])
+               die("%s: Illegal bss segment");
+       if (lb[7])
+               die("%s: Illegal symbol table");
 }
 
 void usage(void)
 {
-       die("Usage: build bootsect setup system [rootdev] [> image]");
+       die("Usage: build [-b] bootsect setup system [rootdev] [> image]");
 }
 
 int main(int argc, char ** argv)
 {
-       int i,c,id,sz,tmp_int;
-       unsigned long sys_size, tmp_long;
-       char buf[1024];
-#ifndef __BFD__
-       struct exec *ex = (struct exec *)buf;
-#endif
-       char major_root, minor_root;
+       unsigned int i, c, sz, setup_sectors;
+       u32 sys_size;
+       byte major_root, minor_root;
        struct stat sb;
-       unsigned char setup_sectors;
 
+       if (argc > 2 && !strcmp(argv[1], "-b"))
+         {
+           is_big_kernel = 1;
+           argc--, argv++;
+         }
        if ((argc < 4) || (argc > 5))
                usage();
        if (argc > 4) {
@@ -143,147 +125,79 @@ int main(int argc, char ** argv)
                minor_root = DEFAULT_MINOR_ROOT;
        }
        fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
-       for (i=0;i<sizeof buf; i++) buf[i]=0;
-       if ((id=open(argv[1],O_RDONLY,0))<0)
-               die("Unable to open 'boot'");
-       if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
-               die("Unable to read header of 'boot'");
-       if (((long *) buf)[0]!=intel_long(0x04100301))
-               die("Non-Minix header of 'boot'");
-       if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
-               die("Non-Minix header of 'boot'");
-       if (((long *) buf)[3] != 0)
-               die("Illegal data segment in 'boot'");
-       if (((long *) buf)[4] != 0)
-               die("Illegal bss in 'boot'");
-       if (((long *) buf)[5] != 0)
-               die("Non-Minix header of 'boot'");
-       if (((long *) buf)[7] != 0)
-               die("Illegal symbol table in 'boot'");
-       i=read(id,buf,sizeof buf);
+
+       minix_open(argv[1]);                                /* Copy the boot sector */
+       i = read(fd, buf, sizeof(buf));
        fprintf(stderr,"Boot sector %d bytes.\n",i);
        if (i != 512)
                die("Boot block must be exactly 512 bytes");
-       if ((*(unsigned short *)(buf+510)) != (unsigned short)intel_short(0xAA55))
+       if (buf[510] != 0x55 || buf[511] != 0xaa)
                die("Boot block hasn't got boot flag (0xAA55)");
-       buf[508] = (char) minor_root;
-       buf[509] = (char) major_root;   
-       i=write(1,buf,512);
-       if (i!=512)
+       buf[508] = minor_root;
+       buf[509] = major_root;
+       if (write(1, buf, 512) != 512)
                die("Write call failed");
-       close (id);
-       
-       if ((id=open(argv[2],O_RDONLY,0))<0)
-               die("Unable to open 'setup'");
-       if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
-               die("Unable to read header of 'setup'");
-       if (((long *) buf)[0]!=intel_long(0x04100301))
-               die("Non-Minix header of 'setup'");
-       if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
-               die("Non-Minix header of 'setup'");
-       if (((long *) buf)[3] != 0)
-               die("Illegal data segment in 'setup'");
-       if (((long *) buf)[4] != 0)
-               die("Illegal bss in 'setup'");
-       if (((long *) buf)[5] != 0)
-               die("Non-Minix header of 'setup'");
-       if (((long *) buf)[7] != 0)
-               die("Illegal symbol table in 'setup'");
-       for (i=0 ; (c=read(id,buf,sizeof buf))>0 ; i+=c )
-#ifdef __BIG_KERNEL__
-       {
-               if (!i) {
-                       /* Working with memcpy because of alignment constraints
-                          on Sparc - Gertjan */
-                       memcpy(&tmp_long, &buf[2], sizeof(long));
-                       if (tmp_long != intel_long(0x53726448) )
-                               die("Wrong magic in loader header of 'setup'");
-                       memcpy(&tmp_int, &buf[6], sizeof(int));
-                       if (tmp_int < intel_int(0x200))
-                               die("Wrong version of loader header of 'setup'");
-                       buf[0x11] = 1; /* LOADED_HIGH */
-                       tmp_long = intel_long(0x100000);
-                       memcpy(&buf[0x14], &tmp_long, sizeof(long));  /* code32_start */
-               }
-#endif
-               if (write(1,buf,c)!=c)
+       close (fd);
+
+       minix_open(argv[2]);                                /* Copy the setup code */
+       for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c )
+               if (write(1, buf, c) != c)
                        die("Write call failed");
-#ifdef __BIG_KERNEL__
-       }
-#endif
        if (c != 0)
-               die("read-error on 'setup'");
-       close (id);
-       setup_sectors = (unsigned char)((i + 511) / 512);
-       /* for compatibility with LILO */
+               die("read-error on `setup'");
+       close (fd);
+
+       setup_sectors = (i + 511) / 512;                    /* Pad unused space with zeros */
+       /* for compatibility with ancient versions of LILO */
        if (setup_sectors < SETUP_SECTS)
                setup_sectors = SETUP_SECTS;
-       fprintf(stderr,"Setup is %d bytes.\n",i);
-       for (c=0 ; c<sizeof(buf) ; c++)
-               buf[c] = '\0';
+       fprintf(stderr, "Setup is %d bytes.\n", i);
+       memset(buf, sizeof(buf), 0);
        while (i < setup_sectors * 512) {
                c = setup_sectors * 512 - i;
                if (c > sizeof(buf))
                        c = sizeof(buf);
-               if (write(1,buf,c) != c)
+               if (write(1, buf, c) != c)
                        die("Write call failed");
                i += c;
        }
-       
-       if ((id=open(argv[3],O_RDONLY,0))<0)
-               die("Unable to open 'system'");
-#ifndef __BFD__
-       if (read(id,buf,GCC_HEADER) != GCC_HEADER)
-               die("Unable to read header of 'system'");
-       if (N_MAGIC(*ex) == ZMAGIC) {
-               GCC_HEADER = N_MAGIC_OFFSET;
-               lseek(id, GCC_HEADER, SEEK_SET);
-       } else if (N_MAGIC(*ex) != QMAGIC)
-               die("Non-GCC header of 'system'");
-       fprintf(stderr,"System is %d kB (%d kB code, %d kB data and %d kB bss)\n",
-               (ex->a_text+ex->a_data+ex->a_bss)/1024,
-               ex->a_text /1024,
-               ex->a_data /1024,
-               ex->a_bss  /1024);
-       sz = N_SYMOFF(*ex) - GCC_HEADER + 4;
-#else
-       if (fstat (id, &sb)) {
-         perror ("fstat");
-         die ("Unable to stat 'system'");
-       }
+
+       if ((fd = open(argv[3], O_RDONLY, 0)) < 0)          /* Copy the image itself */
+               die("Unable to open `%s': %m", argv[3]);
+       if (fstat (fd, &sb))
+               die("Unable to stat `%s': %m", argv[3]);
        sz = sb.st_size;
        fprintf (stderr, "System is %d kB\n", sz/1024);
-#endif
        sys_size = (sz + 15) / 16;
-       if (sys_size > SYS_SIZE)
+       if (sys_size > (is_big_kernel ? 0xffff : DEF_SYSSIZE))
                die("System is too big");
        while (sz > 0) {
                int l, n;
 
-               l = sz;
-               if (l > sizeof(buf))
-                       l = sizeof(buf);
-               if ((n=read(id, buf, l)) != l) {
-                       if (n == -1) 
-                               perror(argv[1]);
+               l = (sz > sizeof(buf)) ? sizeof(buf) : sz;
+               if ((n=read(fd, buf, l)) != l) {
+                       if (n < 0)
+                               die("Error reading %s: %m", argv[3]);
                        else
-                               fprintf(stderr, "Unexpected EOF\n");
-                       die("Can't read 'system'");
+                               die("%s: Unexpected EOF", argv[3]);
                }
                if (write(1, buf, l) != l)
                        die("Write failed");
                sz -= l;
        }
-       close(id);
-       if (lseek(1, 497, 0) == 497) {
-               if (write(1, &setup_sectors, 1) != 1)
-                       die("Write of setup sectors failed");
-       }
-       if (lseek(1,500,0) == 500) {
-               buf[0] = (sys_size & 0xff);
-               buf[1] = ((sys_size >> 8) & 0xff);
-               if (write(1, buf, 2) != 2)
-                       die("Write failed");
-       }
-       return(0);
+       close(fd);
+
+       if (lseek(1, 497, SEEK_SET) != 497)                 /* Write sizes to the bootsector */
+               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);
+       if (write(1, buf, 2) != 2)
+               die("Write of image length failed");
+
+       return 0;                                           /* Everything is OK */
 }
index 152d66a7a45f401fdaece9a2399fd20370ef40cc..58c08b189b8375bb68fd7bce7a36c6a469f491e2 100644 (file)
@@ -59,6 +59,7 @@
 #include <linux/kernel.h>
 #include <linux/bios32.h>
 #include <linux/pci.h>
+#include <linux/init.h>
 
 #include <asm/page.h>
 #include <asm/segment.h>
@@ -188,7 +189,7 @@ static struct {
 } pci_indirect = { 0, KERNEL_CS };
 
 
-extern unsigned long check_pcibios(unsigned long memory_start, unsigned long memory_end)
+__initfunc(static unsigned long check_pcibios(unsigned long memory_start, unsigned long memory_end))
 {
        unsigned long signature;
        unsigned char present_status;
@@ -710,7 +711,7 @@ static struct pci_access pci_direct_conf2 = {
 };
 
 
-static struct pci_access *check_direct_pci(void)
+__initfunc(static struct pci_access *check_direct_pci(void))
 {
     unsigned int tmp;
     unsigned long flags;
@@ -863,14 +864,14 @@ const char *pcibios_strerror (int error)
 }
 
 
-unsigned long pcibios_fixup(unsigned long mem_start, unsigned long mem_end)
+__initfunc(unsigned long pcibios_fixup(unsigned long mem_start, unsigned long mem_end))
 {
     return mem_start;
 }
 
 #endif
 
-unsigned long pcibios_init(unsigned long memory_start, unsigned long memory_end)
+__initfunc(unsigned long pcibios_init(unsigned long memory_start, unsigned long memory_end))
 {
 #ifdef CONFIG_PCI
        union bios32 *check;
index a7eca49d675b438187325ad5ccb37992aa9c1cbb..fc06be2b81d1ae6ec4d14ab4dad8052e1a11bdce 100644 (file)
@@ -89,7 +89,7 @@ startup_32:
  * Clear BSS first so that there are no surprises...
  */
        xorl %eax,%eax
-       movl $ SYMBOL_NAME(_edata),%edi
+       movl $ SYMBOL_NAME(__bss_start),%edi
        movl $ SYMBOL_NAME(_end),%ecx
        subl %edi,%ecx
        cld
index c09096234297995bd03038462dc46258d2525440..90f2ff8eab97eddcd92ba5479e204a07bd25f8a0 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/random.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
@@ -35,6 +36,8 @@
 #include <asm/smp.h>
 #include <asm/pgtable.h>
 
+#include "irq.h"
+
 #ifdef __SMP_PROF__
 extern volatile unsigned long smp_local_timer_ticks[1+NR_CPUS];
 #endif
@@ -146,10 +149,8 @@ BUILD_IRQ(SECOND,15,0x80)
 BUILD_SMP_INTERRUPT(reschedule_interrupt)
 BUILD_SMP_INTERRUPT(invalidate_interrupt)
 BUILD_SMP_INTERRUPT(stop_cpu_interrupt)
-#ifdef __SMP_PROF__
 BUILD_SMP_TIMER_INTERRUPT(apic_timer_interrupt)
 #endif
-#endif
 
 /*
  * Pointers to the low-level handlers: first the general ones, then the
@@ -524,40 +525,6 @@ void __global_restore_flags(unsigned long flags)
        }
 }
 
-#undef INIT_STUCK
-#define INIT_STUCK 200000000
-
-#undef STUCK
-#define STUCK \
-if (!--stuck) {printk("irq_enter stuck (irq=%d, cpu=%d, global=%d)\n",irq,cpu,global_irq_holder); stuck = INIT_STUCK;}
-
-inline void irq_enter(int cpu, int irq)
-{
-       int stuck = INIT_STUCK;
-
-       hardirq_enter(cpu);
-       while (test_bit(0,&global_irq_lock)) {
-               if ((unsigned char) cpu == global_irq_holder) {
-                       printk("BAD! Local interrupts enabled, global disabled\n");
-                       break;
-               }
-               STUCK;
-               /* nothing */;
-       }
-}
-
-inline void irq_exit(int cpu, int irq)
-{
-       __cli();
-       hardirq_exit(cpu);
-       release_irqlock(cpu);
-}
-
-#else
-
-#define irq_enter(cpu, irq)    (++local_irq_count[cpu])
-#define irq_exit(cpu, irq)     (--local_irq_count[cpu])
-
 #endif
 
 /*
@@ -754,7 +721,7 @@ int probe_irq_off (unsigned long irqs)
        return i;
 }
 
-void init_IRQ(void)
+__initfunc(void init_IRQ(void))
 {
        int i;
        static unsigned char smptrap=0;
@@ -777,19 +744,25 @@ void init_IRQ(void)
         */
 
 #ifdef __SMP__ 
-       /* IRQ '16' - IPI for rescheduling */
+       /*
+        * NOTE! The local APIC isn't very good at handling
+        * multiple interrupts at the same interrupt level.
+        * As the interrupt level is determined by taking the
+        * vector number and shifting that right by 4, we
+        * want to spread these out a bit so that they don't
+        * all fall in the same interrupt level
+        */
+       /* IRQ '16' (trap 0x30) - IPI for rescheduling */
        set_intr_gate(0x20+i, reschedule_interrupt);
 
-       /* IRQ '17' - IPI for invalidation */
+       /* IRQ '17' (trap 0x31) - IPI for invalidation */
        set_intr_gate(0x21+i, invalidate_interrupt);
 
-       /* IRQ '18' - IPI for CPU halt */
-       set_intr_gate(0x22+i, stop_cpu_interrupt);
+       /* IRQ '18' (trap 0x40) - IPI for CPU halt */
+       set_intr_gate(0x30+i, stop_cpu_interrupt);
 
-#ifdef __SMP_PROF__
-       /* IRQ '19' - self generated IPI for local APIC timer */
-       set_intr_gate(0x23+i, apic_timer_interrupt);
-#endif
+       /* IRQ '19' (trap 0x41) - self generated IPI for local APIC timer */
+       set_intr_gate(0x31+i, apic_timer_interrupt);
 #endif 
        request_region(0x20,0x20,"pic1");
        request_region(0xa0,0x20,"pic2");
diff --git a/arch/i386/kernel/irq.h b/arch/i386/kernel/irq.h
new file mode 100644 (file)
index 0000000..365344a
--- /dev/null
@@ -0,0 +1,269 @@
+#ifndef __irq_h
+#define __irq_h
+
+/*
+ * Various low-level irq details needed by irq.c and smp.c
+ *
+ * Interrupt entry/exit code at both C and assembly level
+ */
+
+#ifdef __SMP__
+
+#undef INIT_STUCK
+#define INIT_STUCK 200000000
+
+#undef STUCK
+#define STUCK \
+if (!--stuck) {printk("irq_enter stuck (irq=%d, cpu=%d, global=%d)\n",irq,cpu,global_irq_holder); stuck = INIT_STUCK;}
+
+static inline void irq_enter(int cpu, int irq)
+{
+       int stuck = INIT_STUCK;
+
+       hardirq_enter(cpu);
+       while (test_bit(0,&global_irq_lock)) {
+               if ((unsigned char) cpu == global_irq_holder) {
+                       printk("BAD! Local interrupts enabled, global disabled\n");
+                       break;
+               }
+               STUCK;
+               /* nothing */;
+       }
+}
+
+static inline void irq_exit(int cpu, int irq)
+{
+       __cli();
+       hardirq_exit(cpu);
+       release_irqlock(cpu);
+}
+
+#else
+
+#define irq_enter(cpu, irq)    (++local_irq_count[cpu])
+#define irq_exit(cpu, irq)     (--local_irq_count[cpu])
+
+#endif
+
+#define __STR(x) #x
+#define STR(x) __STR(x)
+
+#define SAVE_ALL \
+       "cld\n\t" \
+       "push %es\n\t" \
+       "push %ds\n\t" \
+       "pushl %eax\n\t" \
+       "pushl %ebp\n\t" \
+       "pushl %edi\n\t" \
+       "pushl %esi\n\t" \
+       "pushl %edx\n\t" \
+       "pushl %ecx\n\t" \
+       "pushl %ebx\n\t" \
+       "movl $" STR(KERNEL_DS) ",%edx\n\t" \
+       "mov %dx,%ds\n\t" \
+       "mov %dx,%es\n\t"
+
+/*
+ * SAVE_MOST/RESTORE_MOST is used for the faster version of IRQ handlers,
+ * installed by using the SA_INTERRUPT flag. These kinds of IRQ's don't
+ * call the routines that do signal handling etc on return, and can have
+ * more relaxed register-saving etc. They are also atomic, and are thus
+ * suited for small, fast interrupts like the serial lines or the harddisk
+ * drivers, which don't actually need signal handling etc.
+ *
+ * Also note that we actually save only those registers that are used in
+ * C subroutines (%eax, %edx and %ecx), so if you do something weird,
+ * you're on your own. The only segments that are saved (not counting the
+ * automatic stack and code segment handling) are %ds and %es, and they
+ * point to kernel space. No messing around with %fs here.
+ */
+#define SAVE_MOST \
+       "cld\n\t" \
+       "push %es\n\t" \
+       "push %ds\n\t" \
+       "pushl %eax\n\t" \
+       "pushl %edx\n\t" \
+       "pushl %ecx\n\t" \
+       "movl $" STR(KERNEL_DS) ",%edx\n\t" \
+       "mov %dx,%ds\n\t" \
+       "mov %dx,%es\n\t"
+
+#define RESTORE_MOST \
+       "popl %ecx\n\t" \
+       "popl %edx\n\t" \
+       "popl %eax\n\t" \
+       "pop %ds\n\t" \
+       "pop %es\n\t" \
+       "iret"
+
+/*
+ * Some fast irq handlers might want to access saved registers (mostly
+ * cs or flags)
+ */
+
+struct fast_irq_regs {
+       long ecx;
+       long edx;
+       long eax;
+       int  xds;
+       int  xes;
+       long eip;
+       int  xcs;
+       long eflags;
+       long esp;
+       int  xss;
+};
+
+/*
+ * The "inb" instructions are not needed, but seem to change the timings
+ * a bit - without them it seems that the harddisk driver won't work on
+ * all hardware. Arghh.
+ */
+#define ACK_FIRST(mask,nr) \
+       "inb $0x21,%al\n\t" \
+       "jmp 1f\n" \
+       "1:\tjmp 1f\n" \
+       "1:\torb $" #mask ","SYMBOL_NAME_STR(cache_21)"\n\t" \
+       "movb "SYMBOL_NAME_STR(cache_21)",%al\n\t" \
+       "outb %al,$0x21\n\t" \
+       "jmp 1f\n" \
+       "1:\tjmp 1f\n" \
+       "1:\tmovb $0x20,%al\n\t" \
+       "outb %al,$0x20\n\t"
+
+#define ACK_SECOND(mask,nr) \
+       "inb $0xA1,%al\n\t" \
+       "jmp 1f\n" \
+       "1:\tjmp 1f\n" \
+       "1:\torb $" #mask ","SYMBOL_NAME_STR(cache_A1)"\n\t" \
+       "movb "SYMBOL_NAME_STR(cache_A1)",%al\n\t" \
+       "outb %al,$0xA1\n\t" \
+       "jmp 1f\n" \
+       "1:\tjmp 1f\n" \
+       "1:\tmovb $0x20,%al\n\t" \
+       "outb %al,$0xA0\n\t" \
+       "jmp 1f\n" \
+       "1:\tjmp 1f\n" \
+       "1:\toutb %al,$0x20\n\t"
+
+#define UNBLK_FIRST(mask) \
+       "inb $0x21,%al\n\t" \
+       "jmp 1f\n" \
+       "1:\tjmp 1f\n" \
+       "1:\tandb $~(" #mask "),"SYMBOL_NAME_STR(cache_21)"\n\t" \
+       "movb "SYMBOL_NAME_STR(cache_21)",%al\n\t" \
+       "outb %al,$0x21\n\t"
+
+#define UNBLK_SECOND(mask) \
+       "inb $0xA1,%al\n\t" \
+       "jmp 1f\n" \
+       "1:\tjmp 1f\n" \
+       "1:\tandb $~(" #mask "),"SYMBOL_NAME_STR(cache_A1)"\n\t" \
+       "movb "SYMBOL_NAME_STR(cache_A1)",%al\n\t" \
+       "outb %al,$0xA1\n\t"
+
+#define IRQ_NAME2(nr) nr##_interrupt(void)
+#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
+#define FAST_IRQ_NAME(nr) IRQ_NAME2(fast_IRQ##nr)
+#define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr)
+
+#ifdef __SMP__
+
+#define GET_CURRENT \
+       "movl "SYMBOL_NAME_STR(apic_reg)", %ebx\n\t" \
+       "movl 32(%ebx), %ebx\n\t" \
+       "shrl $22,%ebx\n\t" \
+       "andl $0x3C,%ebx\n\t" \
+       "movl " SYMBOL_NAME_STR(current_set) "(,%ebx),%ebx\n\t"
+       
+#else
+
+#define GET_CURRENT \
+       "movl " SYMBOL_NAME_STR(current_set) ",%ebx\n\t"
+       
+#endif
+
+#ifdef __SMP__
+
+/*
+ *     SMP has a few special interrupts for IPI messages
+ */
+
+#define BUILD_SMP_INTERRUPT(x) \
+asmlinkage void x(void); \
+__asm__( \
+"\n"__ALIGN_STR"\n" \
+SYMBOL_NAME_STR(x) ":\n\t" \
+       "pushl $-1\n\t" \
+       SAVE_ALL \
+       "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \
+       "jmp ret_from_intr\n");
+
+#define BUILD_SMP_TIMER_INTERRUPT(x) \
+asmlinkage void x(struct pt_regs * regs); \
+__asm__( \
+"\n"__ALIGN_STR"\n" \
+SYMBOL_NAME_STR(x) ":\n\t" \
+       "pushl $-1\n\t" \
+        SAVE_ALL \
+        "movl %esp,%eax\n\t" \
+        "pushl %eax\n\t" \
+       "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \
+        "addl $4,%esp\n\t" \
+       "jmp ret_from_intr\n");
+
+#endif /* __SMP__ */
+
+#define BUILD_IRQ(chip,nr,mask) \
+asmlinkage void IRQ_NAME(nr); \
+asmlinkage void FAST_IRQ_NAME(nr); \
+asmlinkage void BAD_IRQ_NAME(nr); \
+__asm__( \
+"\n"__ALIGN_STR"\n" \
+SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
+       "pushl $-"#nr"-2\n\t" \
+       SAVE_ALL \
+       ACK_##chip(mask,(nr&7)) \
+       "movl %esp,%eax\n\t" \
+       "pushl %eax\n\t" \
+       "pushl $" #nr "\n\t" \
+       "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
+       "addl $8,%esp\n\t" \
+       UNBLK_##chip(mask) \
+       "jmp ret_from_intr\n" \
+"\n"__ALIGN_STR"\n" \
+SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
+       SAVE_MOST \
+       ACK_##chip(mask,(nr&7)) \
+       "pushl $" #nr "\n\t" \
+       "call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \
+       "addl $4,%esp\n\t" \
+       UNBLK_##chip(mask) \
+       RESTORE_MOST \
+"\n"__ALIGN_STR"\n" \
+SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
+       SAVE_MOST \
+       ACK_##chip(mask,(nr&7)) \
+       RESTORE_MOST);
+       
+#define BUILD_TIMER_IRQ(chip,nr,mask) \
+asmlinkage void IRQ_NAME(nr); \
+asmlinkage void FAST_IRQ_NAME(nr); \
+asmlinkage void BAD_IRQ_NAME(nr); \
+__asm__( \
+"\n"__ALIGN_STR"\n" \
+SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
+SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
+SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
+       "pushl $-"#nr"-2\n\t" \
+       SAVE_ALL \
+       ACK_##chip(mask,(nr&7)) \
+       "movl %esp,%eax\n\t" \
+       "pushl %eax\n\t" \
+       "pushl $" #nr "\n\t" \
+       "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
+       "addl $8,%esp\n\t" \
+       UNBLK_##chip(mask) \
+       "jmp ret_from_intr\n");
+
+#endif
index 83b0b92c83e91a9a7e24349630460817cb96bf1b..1f8d0799dfca5adb91dbfb896e422f9c77899f3b 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/pagemap.h>
 #include <linux/ioport.h>
 #include <asm/uaccess.h>
+#include <linux/init.h>
 
 /* This structure holds MCA information. Each (plug-in) adapter has 
  * eight POS registers. Then the machine may have integrated video and
@@ -78,7 +79,7 @@ static struct inode_operations proc_mca_inode_operations = {
 
 /*--------------------------------------------------------------------*/
 
-long mca_init(long memory_start, long memory_end)
+__initfunc(long mca_init(long memory_start, long memory_end))
 {
        unsigned int  i, j;
        int foundscsi = 0;
@@ -417,7 +418,7 @@ int  get_mca_info(char *buf)
 
 
 /*--------------------------------------------------------------------*/
-long mca_do_proc_init( long memory_start, long memory_end )
+__initfunc(long mca_do_proc_init( long memory_start, long memory_end ))
 {
        int i = 0;
        struct proc_dir_entry* node = 0;
index 69b07d40dc249b4e85ee150e5bb0a4bcbdf7004a..ec59547719c56db821c2d2833baa2afac46c66d9 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/config.h>
+#include <linux/init.h>
 #ifdef CONFIG_APM
 #include <linux/apm_bios.h>
 #endif
@@ -115,8 +116,8 @@ extern char empty_zero_page[PAGE_SIZE];
 static char command_line[COMMAND_LINE_SIZE] = { 0, };
        char saved_command_line[COMMAND_LINE_SIZE];
 
-void setup_arch(char **cmdline_p,
-       unsigned long * memory_start_p, unsigned long * memory_end_p)
+__initfunc(void 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;
index 399806a0679671ed823ee2135f468660a085ee64..c2f60ef0ecab6658b463408c84d7eb52e65e7ad0 100644 (file)
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/interrupt.h>
+#include <linux/init.h>
 #include <asm/pgtable.h>
 #include <asm/bitops.h>
 #include <asm/pgtable.h>
 #include <asm/smp.h>
 #include <asm/io.h>
 
+#include "irq.h"
+
 extern unsigned long start_kernel, _etext;
 void setup_APIC_clock (void);
 
@@ -170,7 +173,7 @@ volatile int smp_process_available=0;
  *     SMP mode to <NUM>.
  */
 
-void smp_setup(char *str, int *ints)
+__initfunc(void smp_setup(char *str, int *ints))
 {
        if (ints && ints[0] > 0)
                max_cpus = ints[1];
@@ -232,7 +235,7 @@ static char *mpc_family(int family,int model)
  *     Read the MPC
  */
 
-static int smp_read_mpc(struct mp_config_table *mpc)
+__initfunc(static int smp_read_mpc(struct mp_config_table *mpc))
 {
        char str[16];
        int count=sizeof(*mpc);
@@ -377,7 +380,7 @@ static int smp_read_mpc(struct mp_config_table *mpc)
  *     Scan the memory blocks for an SMP configuration block.
  */
  
-int smp_scan_config(unsigned long base, unsigned long length)
+__initfunc(int smp_scan_config(unsigned long base, unsigned long length))
 {
        unsigned long *bp=phys_to_virt(base);
        struct intel_mp_floating *mpf;
@@ -535,7 +538,7 @@ extern unsigned char trampoline_end  [];
  *     has made sure it's suitably aligned.
  */
  
-static void install_trampoline(unsigned char *mp)
+__initfunc(static void install_trampoline(unsigned char *mp))
 {
        memcpy(mp, trampoline_data, trampoline_end - trampoline_data);
 }
@@ -547,7 +550,7 @@ static void install_trampoline(unsigned char *mp)
  *     other things).
  */
  
-unsigned long smp_alloc_memory(unsigned long mem_base)
+__initfunc(unsigned long smp_alloc_memory(unsigned long mem_base))
 {
        int size=(num_processors-1)*PAGE_SIZE;          /* Number of stacks needed */
 
@@ -568,7 +571,7 @@ unsigned long smp_alloc_memory(unsigned long mem_base)
  *     Hand out stacks one at a time.
  */
  
-static void *get_kernel_stack(void)
+__initfunc(static void *get_kernel_stack(void))
 {
        void *stack=kstack_base;
        if(kstack_base>=kstack_end)
@@ -583,7 +586,7 @@ static void *get_kernel_stack(void)
  *     a given CPU
  */
  
-void smp_store_cpu_info(int id)
+__initfunc(void smp_store_cpu_info(int id))
 {
        struct cpuinfo_x86 *c=&cpu_data[id];
        c->hard_math=hard_math;                 /* Always assumed same currently */
@@ -614,7 +617,7 @@ void smp_store_cpu_info(int id)
  *     we use to track CPU's as they power up.
  */
 
-void smp_commence(void)
+__initfunc(void smp_commence(void))
 {
        /*
         *      Lets the callin's below out of their loop.
@@ -623,7 +626,7 @@ void smp_commence(void)
        smp_commenced=1;
 }
 
-void smp_callin(void)
+__initfunc(void smp_callin(void))
 {
        extern void calibrate_delay(void);
        int cpuid=GET_APIC_ID(apic_read(APIC_ID));
@@ -687,7 +690,7 @@ void smp_callin(void)
  *     Cycle through the processors sending APIC IPI's to boot each.
  */
  
-void smp_boot_cpus(void)
+__initfunc(void smp_boot_cpus(void))
 {
        int i;
        int cpucount=0;
@@ -1093,6 +1096,7 @@ void smp_boot_cpus(void)
  
 void smp_message_pass(int target, int msg, unsigned long data, int wait)
 {
+       unsigned long flags;
        unsigned long cfg;
        unsigned long target_map;
        int p=smp_processor_id();
@@ -1121,11 +1125,12 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait)
                        break;
 
                case MSG_INVALIDATE_TLB:
+                       /* make this a NMI some day */
                        irq = 0x31;
                        break;
 
                case MSG_STOP_CPU:
-                       irq = 0x32;
+                       irq = 0x40;
                        break;
 
                default:
@@ -1168,15 +1173,15 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait)
         *      Just pray... there is nothing more we can do
         */
         
-       if(ct==1000) {
-               printk("CPU #%d: previous IPI still not cleared after 10mS", p);
-               ack_APIC_irq ();
-       }
+       if(ct==1000)
+               printk("CPU #%d: previous IPI still not cleared after 10mS\n", p);
                
        /*
         *      Program the APIC to deliver the IPI
         */
-        
+
+       __save_flags(flags);
+       __cli();
        cfg=apic_read(APIC_ICR2);
        cfg&=0x00FFFFFF;
        apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(target));                 /* Target chip                  */
@@ -1210,7 +1215,8 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait)
         *      Send the IPI. The write to APIC_ICR fires this off.
         */
         
-       apic_write(APIC_ICR, cfg);      
+       apic_write(APIC_ICR, cfg);
+       __restore_flags(flags);
        
        /*
         *      Spin waiting for completion
@@ -1300,36 +1306,6 @@ void smp_flush_tlb(void)
 /*     printk("SMID\n");*/
 }
 
-/*     
- *     Reschedule call back
- */
-asmlinkage void smp_reschedule_interrupt(void)
-{
-       need_resched=1;
-       ack_APIC_irq();
-}
-
-/*
- * Invalidate call-back
- */
-asmlinkage void smp_invalidate_interrupt(void)
-{
-       if (clear_bit(smp_processor_id(), &smp_invalidate_needed))
-               local_flush_tlb();
-
-       ack_APIC_irq ();
-}      
-
-/*
- *     CPU halt call-back
- */
-asmlinkage void smp_stop_cpu_interrupt(void)
-{
-       if (cpu_data[smp_processor_id()].hlt_works_ok)
-               for(;;) __asm__("hlt");
-       for  (;;) ;
-}
-
 /*
  * Platform specific profiling function.
  * it builds a 'prof_shift' resolution EIP distribution histogram
@@ -1337,7 +1313,7 @@ asmlinkage void smp_stop_cpu_interrupt(void)
  * it's SMP safe.
  */
 
-inline void x86_do_profile (unsigned long eip)
+static inline void x86_do_profile (unsigned long eip)
 {
        if (prof_buffer && current->pid) {
                extern int _stext;
@@ -1394,9 +1370,6 @@ static inline void smp_local_timer_interrupt(struct pt_regs * regs)
                 *
                 * kernel statistics counters are updated via atomic
                 * operations.
-                *
-                * update_one_process() might send signals, thus
-                * we have to get the irq lock for that one.
                 */
 
                if (user_mode(regs))
@@ -1405,12 +1378,7 @@ static inline void smp_local_timer_interrupt(struct pt_regs * regs)
                        system=1;
 
                if (p->pid) {
-                       unsigned long flags;
-       
-                       save_flags(flags);
-                       cli();
-                       update_one_process(current, 1, user, system);
-                       restore_flags(flags);
+                       update_one_process(p, 1, user, system);
 
                        p->counter -= 1;
                        if (p->counter < 0) {
@@ -1464,9 +1432,63 @@ static inline void smp_local_timer_interrupt(struct pt_regs * regs)
  */
 void smp_apic_timer_interrupt(struct pt_regs * regs)
 {
+       int cpu = smp_processor_id();
+
+       /*
+        * NOTE! We'd better ACK the irq immediately,
+        * because timer handling can be slow, and we
+        * want to be able to accept NMI tlb invalidates
+        * during this time.
+        */
+       ack_APIC_irq ();
+
+       /*
+        * After doing the above, we need to make like
+        * a normal interrupt - otherwise timer interrupts
+        * ignore the global interrupt lock, which is the
+        * WrongThing (tm) to do.
+        */
+       irq_enter(cpu, 0);
        smp_local_timer_interrupt(regs);
+       irq_exit(cpu, 0);
+}
+
+/*     
+ *     Reschedule call back
+ */
+asmlinkage void smp_reschedule_interrupt(void)
+{
+       int cpu = smp_processor_id();
+
+       ack_APIC_irq();
+       /*
+        * This looks silly, but we actually do need to wait
+        * for the global interrupt lock.
+        */
+       irq_enter(cpu, 0);
+       need_resched=1;
+       irq_exit(cpu, 0);
+}
+
+/*
+ * Invalidate call-back
+ */
+asmlinkage void smp_invalidate_interrupt(void)
+{
+       if (clear_bit(smp_processor_id(), &smp_invalidate_needed))
+               local_flush_tlb();
 
        ack_APIC_irq ();
+}      
+
+/*
+ *     CPU halt call-back
+ */
+asmlinkage void smp_stop_cpu_interrupt(void)
+{
+       if (cpu_data[smp_processor_id()].hlt_works_ok)
+               for(;;) __asm__("hlt");
+       for  (;;) ;
 }
 
 /*
@@ -1487,7 +1509,7 @@ void smp_apic_timer_interrupt(struct pt_regs * regs)
  * but we do not accept timer interrupts yet. We only allow the BP
  * to calibrate.
  */
-unsigned int get_8254_timer_count (void)
+static unsigned int get_8254_timer_count (void)
 {
        unsigned int count;
 
@@ -1524,11 +1546,11 @@ void setup_APIC_timer (unsigned int clocks)
         * mode. With the IO APIC we can re-route the external timer
         * interrupt and broadcast it as an NMI to all CPUs, so no pain.
         *
-        * NOTE: this irq vector 19 and the gate in BUILD_SMP_TIMER_INTERRUPT
+        * NOTE: this trap vector (0x41) and the gate in BUILD_SMP_TIMER_INTERRUPT
         * should be the same ;)
         */
        tmp_value = apic_read(APIC_LVTT);
-       lvtt1_value = APIC_LVT_TIMER_PERIODIC | (0x20+19);
+       lvtt1_value = APIC_LVT_TIMER_PERIODIC | 0x41;
        apic_write(APIC_LVTT , lvtt1_value);
 
        /*
index 6ef3a282193d9332ebb6377632088fbdd59c5878..974e5c85b865c402767fd07dca45202008336584 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/interrupt.h>
 #include <linux/time.h>
 #include <linux/delay.h>
+#include <linux/init.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -369,7 +370,7 @@ static long last_rtc_update = 0;
  * Move this to a header file - right now it shows
  * up both here and in smp.c
  */
-inline void x86_do_profile (unsigned long eip)
+static inline void x86_do_profile (unsigned long eip)
 {
        if (prof_buffer && current->pid) {
                extern int _stext;
@@ -415,11 +416,13 @@ static inline void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
            last_rtc_update = xtime.tv_sec;
          else
            last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+#if 0
        /* As we return to user mode fire off the other CPU schedulers.. this is 
           basically because we don't yet share IRQ's around. This message is
           rigged to be safe on the 386 - basically it's a hack, so don't look
           closely for now.. */
        smp_message_pass(MSG_ALL_BUT_SELF, MSG_RESCHEDULE, 0L, 0);
+#endif
            
 #ifdef CONFIG_MCA
        if( MCA_bus ) {
@@ -528,7 +531,7 @@ unsigned long get_cmos_time(void)
 static struct irqaction irq0  = { timer_interrupt, 0, 0, "timer", NULL, NULL};
 
 
-void time_init(void)
+__initfunc(void time_init(void))
 {
        xtime.tv_sec = get_cmos_time();
        xtime.tv_usec = 0;
index a89c0a3f512d4d711392be86f1eb948b937a444c..905cf5b13fdafd4943dbe1b088f5c6fbfe409713 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/mm.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
@@ -375,7 +376,7 @@ asmlinkage void math_emulate(long arg)
 
 #endif /* CONFIG_MATH_EMULATION */
 
-void trap_init(void)
+__initfunc(void trap_init(void))
 {
        int i;
        struct desc_struct * p;
index 0089c70a5f36ee57388554671e52cea94238a6c2..f9a925f44e30bc6162b96bc670c3c069793485ce 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/mm.h>
 #include <linux/swap.h>
 #include <linux/smp.h>
+#include <linux/init.h>
 #ifdef CONFIG_BLK_DEV_INITRD
 #include <linux/blk.h>
 #endif
@@ -96,6 +97,11 @@ void show_mem(void)
 
 extern unsigned long free_area_init(unsigned long, unsigned long);
 
+/* References to section boundaries */
+
+extern char _text, _etext, _edata, __bss_start, _end;
+extern char __init_begin, __init_end;
+
 /*
  * paging_init() sets up the page tables - note that the first 4MB are
  * already mapped by head.S.
@@ -103,7 +109,7 @@ extern unsigned long free_area_init(unsigned long, unsigned long);
  * This routines also unmaps the page at virtual kernel address 0, so
  * that we can trap those pesky NULL-reference errors in the kernel.
  */
-unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
+__initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_mem))
 {
        pgd_t * pg_dir;
        pte_t * pg_table;
@@ -202,14 +208,14 @@ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
        return free_area_init(start_mem, end_mem);
 }
 
-void mem_init(unsigned long start_mem, unsigned long end_mem)
+__initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
 {
        unsigned long start_low_mem = PAGE_SIZE;
        int codepages = 0;
        int reservedpages = 0;
        int datapages = 0;
+       int initpages = 0;
        unsigned long tmp;
-       extern int _etext;
 
        end_mem &= PAGE_MASK;
        high_memory = (void *) end_mem;
@@ -251,12 +257,19 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
                if (tmp >= MAX_DMA_ADDRESS)
                        clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags);
                if (PageReserved(mem_map+MAP_NR(tmp))) {
-                       if (tmp >= 0xA0000+PAGE_OFFSET && tmp < 0x100000+PAGE_OFFSET)
-                               reservedpages++;
-                       else if (tmp < (unsigned long) &_etext)
-                               codepages++;
-                       else
+                       if (tmp >= (unsigned long) &_text && tmp < (unsigned long) &_edata) {
+                               if (tmp < (unsigned long) &_etext)
+                                       codepages++;
+                               else
+                                       datapages++;
+                       } else if (tmp >= (unsigned long) &__init_begin
+                                  && tmp < (unsigned long) &__init_end)
+                               initpages++;
+                       else if (tmp >= (unsigned long) &__bss_start
+                                && tmp < (unsigned long) start_mem)
                                datapages++;
+                       else
+                               reservedpages++;
                        continue;
                }
                atomic_set(&mem_map[MAP_NR(tmp)].count, 1);
@@ -266,12 +279,13 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
 #endif
                        free_page(tmp);
        }
-       printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data)\n",
+       printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
                (unsigned long) nr_free_pages << (PAGE_SHIFT-10),
                max_mapnr << (PAGE_SHIFT-10),
                codepages << (PAGE_SHIFT-10),
                reservedpages << (PAGE_SHIFT-10),
-               datapages << (PAGE_SHIFT-10));
+               datapages << (PAGE_SHIFT-10),
+               initpages << (PAGE_SHIFT-10));
 /* test if the WP bit is honoured in supervisor mode */
        if (wp_works_ok < 0) {
                unsigned char tmp_reg;
@@ -300,7 +314,14 @@ void mem_init(unsigned long start_mem, unsigned long end_mem)
 
 void free_initmem(void)
 {
-       /* To be written */
+       unsigned long addr;
+       
+       addr = (unsigned long)(&__init_begin);
+       for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
+               mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
+               atomic_set(&mem_map[MAP_NR(addr)].count, 1);
+               free_page(addr);
+       }
 }
 
 void si_meminfo(struct sysinfo *val)
diff --git a/arch/i386/vmlinux.lds b/arch/i386/vmlinux.lds
new file mode 100644 (file)
index 0000000..6d11950
--- /dev/null
@@ -0,0 +1,58 @@
+/* ld script to make i386 Linux kernel
+ * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ */
+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
+OUTPUT_ARCH(i386)
+ENTRY(_start)
+SECTIONS
+{
+  . = 0xc0100000;
+  _text = .;                   /* Text and read-only data */
+  .text : {
+       *(.text)
+       *(.fixup)
+       *(.gnu.warning)
+       } = 0x9090
+  .rodata : { *(.rodata) }
+  .kstrtab : { *(.kstrtab) }
+
+  . = ALIGN(16);               /* Exception table */
+  __start___ex_table = .;
+  __ex_table : { *(__ex_table) }
+  __stop___ex_table = .;
+
+  __start___ksymtab = .;       /* Kernel symbol table */
+  __ksymtab : { *(__ksymtab) }
+  __stop___ksymtab = .;
+
+  _etext = .;                  /* End of text section */
+
+  .data : {                    /* Data */
+       *(.data)
+       CONSTRUCTORS
+       }
+
+  _edata = .;                  /* End of data section */
+
+  . = ALIGN(4096);             /* Init code and data */
+  __init_begin = .;
+  .text.init : { *(.text.init) }
+  .data.init : { *(.data.init) }
+  . = ALIGN(4096);
+  __init_end = .;
+
+  __bss_start = .;             /* BSS */
+  .bss : {
+       *(.bss)
+       }
+  _end = . ;
+
+  /* Stabs debugging sections.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment 0 : { *(.comment) }
+}
index 7c9e5f1b2f49e59987204de14450f7d7997af340..bbe4d3cd966c2bc84dda44e2cba60ec591d34845 100644 (file)
 #include <asm/system.h>
 #include <asm/poll.h>
 
+/* Adjust starting epoch if ARC console time is being used */
+#ifdef CONFIG_RTC_ARC
+#define ARCFUDGE 20 
+#else
+#define ARCFUDGE 0
+#endif
+
 /*
  *     We sponge a minor off of the misc major. No need slurping
  *     up another valuable major dev number for this. If you add
@@ -336,7 +343,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
 
                        copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time));
 
-                       yrs = rtc_tm.tm_year + 1900;
+                       yrs = rtc_tm.tm_year + 1900 + ARCFUDGE;
                        mon = rtc_tm.tm_mon + 1;   /* tm_mon starts at zero */
                        day = rtc_tm.tm_mday;
                        hrs = rtc_tm.tm_hour;
@@ -725,6 +732,9 @@ void get_rtc_time(struct rtc_time *rtc_tm)
        if (rtc_tm->tm_year <= 69)
                rtc_tm->tm_year += 100;
 
+       /* if ARCFUDGE == 0, the optimizer should do away with this */
+       rtc_tm->tm_year -= ARCFUDGE;
+
        rtc_tm->tm_mon--;
 }
 
diff --git a/drivers/net/de4x5.c.lock~ b/drivers/net/de4x5.c.lock~
deleted file mode 100644 (file)
index 860783b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-torvalds@penguin.transmeta.com
\ No newline at end of file
index e4830278121a946fabcf7d1200d15ccaa9d09527..6390bb6c983d0b3ab58fd9b4a00db8dbc2c883b5 100644 (file)
@@ -491,7 +491,7 @@ repeat:
        inode = first_inode;
        best = NULL;
        badness = 1000;
-       for (i = nr_inodes/2; i > 0; i--,inode = inode->i_prev) {
+       for (i = nr_inodes/2; i > 0; i--,inode = inode->i_next) {
                if (!inode->i_count) {
                        unsigned long i = 999;
                        if (!(inode->i_lock | inode->i_dirt))
index 6dfbf21813ae8fa62c8ccc80f0795f6d9f9a9e68..ba62e86845f439f713b6e19e9b767b69cb7b9c37 100644 (file)
@@ -18,7 +18,7 @@ typedef struct { int counter; } atomic_t;
 #define ATOMIC_INIT    { 0 }
 
 #define atomic_read(v)         ((v)->counter)
-#define atomic_set(v)          (((v)->counter) = i)
+#define atomic_set(v,i)                ((v)->counter = (i))
 
 /*
  * Make sure gcc doesn't try to be clever and move things around
index 3641c3460052ae6b3287e199f53470955bd19087..724f03b77fd0217fa595f151dc4ab1032c4d3f00 100644 (file)
 #define        ERESTART        127     /* Interrupted system call should be restarted */
 #define        ESTRPIPE        128     /* Streams pipe error */
 
+#define ENOMEDIUM      129     /* No medium found */
+#define EMEDIUMTYPE    130     /* Wrong medium type */
+
 #endif
diff --git a/include/asm-alpha/init.h b/include/asm-alpha/init.h
new file mode 100644 (file)
index 0000000..8eb924c
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _ALPHA_INIT_H
+#define _ALPHA_INIT_H
+
+/* Throwing the initialization code and data out is not supported yet... */
+
+#define        __init
+#define __initdata
+#define __initfunc(__arginit) __arginit
+/* For assembly routines */
+#define __INIT
+#define __FINIT
+#define __INITDATA
+
+#endif
index bf2a380e9743dbdd13409bbb281f83c9714913bd..c1f6939c0e1c891058440eedec43ae5affafeb17 100644 (file)
 extern void disable_irq(unsigned int);
 extern void enable_irq(unsigned int);
 
-#define __STR(x) #x
-#define STR(x) __STR(x)
-#define SAVE_ALL "xx"
-
-/*
- * SAVE_MOST/RESTORE_MOST is used for the faster version of IRQ handlers,
- * installed by using the SA_INTERRUPT flag. These kinds of IRQ's don't
- * call the routines that do signal handling etc on return, and can have
- * more relaxed register-saving etc. They are also atomic, and are thus
- * suited for small, fast interrupts like the serial lines or the harddisk
- * drivers, which don't actually need signal handling etc.
- *
- * Also note that we actually save only those registers that are used in
- * C subroutines, so if you do something weird, you're on your own. 
- */
-#define SAVE_MOST "yy"
-
-#define RESTORE_MOST "zz"
-
-#define ACK_FIRST(mask) "aa"
-
-#define ACK_SECOND(mask) "dummy"
-
-#define UNBLK_FIRST(mask) "dummy"
-
-#define UNBLK_SECOND(mask) "dummy"
-
-#define IRQ_NAME2(nr) nr##_interrupt(void)
-#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
-#define FAST_IRQ_NAME(nr) IRQ_NAME2(fast_IRQ##nr)
-#define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr)
-       
-#define BUILD_IRQ(chip,nr,mask) \
-asmlinkage void IRQ_NAME(nr); \
-asmlinkage void FAST_IRQ_NAME(nr); \
-asmlinkage void BAD_IRQ_NAME(nr); \
-asm code comes here
-
 #endif
index 2cfec742e6ab20080ea4e32c2358cc6b46e33018..c073337e6a2170b24de3788ad4131a6a39df4e1b 100644 (file)
@@ -24,18 +24,35 @@ extern void __up(struct semaphore * sem);
 
 #define sema_init(sem, val)    atomic_set(&((sem)->count), val)
 
+/*
+ * These two _must_ execute atomically wrt each other.
+ *
+ * This is trivially done with load_locked/store_cond,
+ * which we have.  Let the rest of the losers suck eggs.
+ */
+
+static inline void wake_one_more(struct semaphore * sem)
+{
+       atomic_inc(&sem->waking);
+}
+
 static inline int waking_non_zero(struct semaphore *sem)
 {
-       unsigned long flags;
-       int ret = 0;
+       int ret, tmp;
+
+       __asm__ __volatile__(
+       "1:     ldl_l   %1,%2\n"
+       "       ble     %1,2f\n"
+       "       subl    %1,1,%0\n"
+       "       stl_c   %0,%2\n"
+       "       beq     %0,3f\n"
+       "2:\n"
+       ".text 2\n"
+       "3:     br      1b\n"
+       ".text"
+       : "=r"(ret), "=r"(tmp), "=m"(__atomic_fool_gcc(&sem->waking))
+       : "0"(0));
 
-       save_flags(flags);
-       cli();
-       if (atomic_read(&sem->waking) > 0) {
-               atomic_dec(&sem->waking);
-               ret = 1;
-       }
-       restore_flags(flags);
        return ret;
 }
 
index a5e40f29725a30bf646bfce8f40d32d65cff9b16..2c4af2336585656390b1d90500b2d335acd197aa 100644 (file)
@@ -34,10 +34,12 @@ typedef struct {
 typedef struct { unsigned long a[100]; } __dummy_lock_t;
 #define __dummy_lock(lock) (*(__dummy_lock_t *)(lock))
 
-#define spin_unlock(lock)                              \
-       __asm__ __volatile__(                           \
-       "mb; stq $31,%0"                                \
-       :"=m" (__dummy_lock(lock)))
+static inline void spin_unlock(spinlock_t * lock)
+{
+       __asm__ __volatile__(
+       "mb; stq $31,%0"
+       :"=m" (__dummy_lock(lock)));
+}
 
 static inline void spin_lock(spinlock_t * lock)
 {
diff --git a/include/asm-i386/boot.h b/include/asm-i386/boot.h
new file mode 100644 (file)
index 0000000..96b228e
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef _LINUX_BOOT_H
+#define _LINUX_BOOT_H
+
+/* Don't touch these, unless you really know what you're doing. */
+#define DEF_INITSEG    0x9000
+#define DEF_SYSSEG     0x1000
+#define DEF_SETUPSEG   0x9020
+#define DEF_SYSSIZE    0x7F00
+
+/* Internal svga startup constants */
+#define NORMAL_VGA     0xffff          /* 80x25 mode */
+#define EXTENDED_VGA   0xfffe          /* 80x50 mode */
+#define ASK_VGA                0xfffd          /* ask for it at bootup */
+
+#endif
diff --git a/include/asm-i386/init.h b/include/asm-i386/init.h
new file mode 100644 (file)
index 0000000..de13c5a
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef _I386_INIT_H
+#define _I386_INIT_H
+
+#ifndef MODULE
+#define __init __attribute__ ((__section__ (".text.init")))
+#define __initdata __attribute__ ((__section__ (".data.init")))
+#define __initfunc(__arginit) \
+       __arginit __init; \
+       __arginit
+/* For assembly routines */
+#define __INIT         .section        ".text.init",#alloc,#execinstr
+#define __FINIT        .previous
+#define __INITDATA     .section        ".data.init",#alloc,#write
+#else
+#define        __init
+#define __initdata
+#define __initfunc(__arginit) __arginit
+/* For assembly routines */
+#define __INIT
+#define __FINIT
+#define __INITDATA
+#endif
+
+#endif
index d9ff5e78ec6c89d6d7457e2362515f93c135f15a..d764ef164f88f34fb63fa894e2e8afb4978c293e 100644 (file)
 extern void disable_irq(unsigned int);
 extern void enable_irq(unsigned int);
 
-#define __STR(x) #x
-#define STR(x) __STR(x)
-
-
-#define SAVE_ALL \
-       "cld\n\t" \
-       "push %es\n\t" \
-       "push %ds\n\t" \
-       "pushl %eax\n\t" \
-       "pushl %ebp\n\t" \
-       "pushl %edi\n\t" \
-       "pushl %esi\n\t" \
-       "pushl %edx\n\t" \
-       "pushl %ecx\n\t" \
-       "pushl %ebx\n\t" \
-       "movl $" STR(KERNEL_DS) ",%edx\n\t" \
-       "mov %dx,%ds\n\t" \
-       "mov %dx,%es\n\t"
-
-/*
- * SAVE_MOST/RESTORE_MOST is used for the faster version of IRQ handlers,
- * installed by using the SA_INTERRUPT flag. These kinds of IRQ's don't
- * call the routines that do signal handling etc on return, and can have
- * more relaxed register-saving etc. They are also atomic, and are thus
- * suited for small, fast interrupts like the serial lines or the harddisk
- * drivers, which don't actually need signal handling etc.
- *
- * Also note that we actually save only those registers that are used in
- * C subroutines (%eax, %edx and %ecx), so if you do something weird,
- * you're on your own. The only segments that are saved (not counting the
- * automatic stack and code segment handling) are %ds and %es, and they
- * point to kernel space. No messing around with %fs here.
- */
-#define SAVE_MOST \
-       "cld\n\t" \
-       "push %es\n\t" \
-       "push %ds\n\t" \
-       "pushl %eax\n\t" \
-       "pushl %edx\n\t" \
-       "pushl %ecx\n\t" \
-       "movl $" STR(KERNEL_DS) ",%edx\n\t" \
-       "mov %dx,%ds\n\t" \
-       "mov %dx,%es\n\t"
-
-#define RESTORE_MOST \
-       "popl %ecx\n\t" \
-       "popl %edx\n\t" \
-       "popl %eax\n\t" \
-       "pop %ds\n\t" \
-       "pop %es\n\t" \
-       "iret"
-
-/*
- * Some fast irq handlers might want to access saved registers (mostly
- * cs or flags)
- */
-
-struct fast_irq_regs {
-       long ecx;
-       long edx;
-       long eax;
-       int  xds;
-       int  xes;
-       long eip;
-       int  xcs;
-       long eflags;
-       long esp;
-       int  xss;
-};
-
-/*
- * The "inb" instructions are not needed, but seem to change the timings
- * a bit - without them it seems that the harddisk driver won't work on
- * all hardware. Arghh.
- */
-#define ACK_FIRST(mask,nr) \
-       "inb $0x21,%al\n\t" \
-       "jmp 1f\n" \
-       "1:\tjmp 1f\n" \
-       "1:\torb $" #mask ","SYMBOL_NAME_STR(cache_21)"\n\t" \
-       "movb "SYMBOL_NAME_STR(cache_21)",%al\n\t" \
-       "outb %al,$0x21\n\t" \
-       "jmp 1f\n" \
-       "1:\tjmp 1f\n" \
-       "1:\tmovb $0x20,%al\n\t" \
-       "outb %al,$0x20\n\t"
-
-#define ACK_SECOND(mask,nr) \
-       "inb $0xA1,%al\n\t" \
-       "jmp 1f\n" \
-       "1:\tjmp 1f\n" \
-       "1:\torb $" #mask ","SYMBOL_NAME_STR(cache_A1)"\n\t" \
-       "movb "SYMBOL_NAME_STR(cache_A1)",%al\n\t" \
-       "outb %al,$0xA1\n\t" \
-       "jmp 1f\n" \
-       "1:\tjmp 1f\n" \
-       "1:\tmovb $0x20,%al\n\t" \
-       "outb %al,$0xA0\n\t" \
-       "jmp 1f\n" \
-       "1:\tjmp 1f\n" \
-       "1:\toutb %al,$0x20\n\t"
-
-#define UNBLK_FIRST(mask) \
-       "inb $0x21,%al\n\t" \
-       "jmp 1f\n" \
-       "1:\tjmp 1f\n" \
-       "1:\tandb $~(" #mask "),"SYMBOL_NAME_STR(cache_21)"\n\t" \
-       "movb "SYMBOL_NAME_STR(cache_21)",%al\n\t" \
-       "outb %al,$0x21\n\t"
-
-#define UNBLK_SECOND(mask) \
-       "inb $0xA1,%al\n\t" \
-       "jmp 1f\n" \
-       "1:\tjmp 1f\n" \
-       "1:\tandb $~(" #mask "),"SYMBOL_NAME_STR(cache_A1)"\n\t" \
-       "movb "SYMBOL_NAME_STR(cache_A1)",%al\n\t" \
-       "outb %al,$0xA1\n\t"
-
-#define IRQ_NAME2(nr) nr##_interrupt(void)
-#define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr)
-#define FAST_IRQ_NAME(nr) IRQ_NAME2(fast_IRQ##nr)
-#define BAD_IRQ_NAME(nr) IRQ_NAME2(bad_IRQ##nr)
-
-#ifdef __SMP__
-
-#define GET_CURRENT \
-       "movl "SYMBOL_NAME_STR(apic_reg)", %ebx\n\t" \
-       "movl 32(%ebx), %ebx\n\t" \
-       "shrl $22,%ebx\n\t" \
-       "andl $0x3C,%ebx\n\t" \
-       "movl " SYMBOL_NAME_STR(current_set) "(,%ebx),%ebx\n\t"
-       
-#else
-
-#define GET_CURRENT \
-       "movl " SYMBOL_NAME_STR(current_set) ",%ebx\n\t"
-       
-#endif
-
-#ifdef __SMP__
-
-/*
- *     SMP has a few special interrupts for IPI messages
- */
-
-#define BUILD_SMP_INTERRUPT(x) \
-asmlinkage void x(void); \
-__asm__( \
-"\n"__ALIGN_STR"\n" \
-SYMBOL_NAME_STR(x) ":\n\t" \
-       "pushl $-1\n\t" \
-       SAVE_ALL \
-       "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \
-       "jmp ret_from_intr\n");
-
-#define BUILD_SMP_TIMER_INTERRUPT(x) \
-asmlinkage void x(struct pt_regs * regs); \
-__asm__( \
-"\n"__ALIGN_STR"\n" \
-SYMBOL_NAME_STR(x) ":\n\t" \
-       "pushl $-1\n\t" \
-        SAVE_ALL \
-        "movl %esp,%eax\n\t" \
-        "pushl %eax\n\t" \
-       "call "SYMBOL_NAME_STR(smp_##x)"\n\t" \
-        "addl $4,%esp\n\t" \
-       "jmp ret_from_intr\n");
-
-#endif /* __SMP__ */
-
-#define BUILD_IRQ(chip,nr,mask) \
-asmlinkage void IRQ_NAME(nr); \
-asmlinkage void FAST_IRQ_NAME(nr); \
-asmlinkage void BAD_IRQ_NAME(nr); \
-__asm__( \
-"\n"__ALIGN_STR"\n" \
-SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
-       "pushl $-"#nr"-2\n\t" \
-       SAVE_ALL \
-       ACK_##chip(mask,(nr&7)) \
-       "movl %esp,%eax\n\t" \
-       "pushl %eax\n\t" \
-       "pushl $" #nr "\n\t" \
-       "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
-       "addl $8,%esp\n\t" \
-       UNBLK_##chip(mask) \
-       "jmp ret_from_intr\n" \
-"\n"__ALIGN_STR"\n" \
-SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
-       SAVE_MOST \
-       ACK_##chip(mask,(nr&7)) \
-       "pushl $" #nr "\n\t" \
-       "call "SYMBOL_NAME_STR(do_fast_IRQ)"\n\t" \
-       "addl $4,%esp\n\t" \
-       UNBLK_##chip(mask) \
-       RESTORE_MOST \
-"\n"__ALIGN_STR"\n" \
-SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
-       SAVE_MOST \
-       ACK_##chip(mask,(nr&7)) \
-       RESTORE_MOST);
-       
-#define BUILD_TIMER_IRQ(chip,nr,mask) \
-asmlinkage void IRQ_NAME(nr); \
-asmlinkage void FAST_IRQ_NAME(nr); \
-asmlinkage void BAD_IRQ_NAME(nr); \
-__asm__( \
-"\n"__ALIGN_STR"\n" \
-SYMBOL_NAME_STR(fast_IRQ) #nr "_interrupt:\n\t" \
-SYMBOL_NAME_STR(bad_IRQ) #nr "_interrupt:\n\t" \
-SYMBOL_NAME_STR(IRQ) #nr "_interrupt:\n\t" \
-       "pushl $-"#nr"-2\n\t" \
-       SAVE_ALL \
-       ACK_##chip(mask,(nr&7)) \
-       "movl %esp,%eax\n\t" \
-       "pushl %eax\n\t" \
-       "pushl $" #nr "\n\t" \
-       "call "SYMBOL_NAME_STR(do_IRQ)"\n\t" \
-       "addl $8,%esp\n\t" \
-       UNBLK_##chip(mask) \
-       "jmp ret_from_intr\n");
-
 #endif /* _ASM_IRQ_H */
diff --git a/include/asm-m68k/init.h b/include/asm-m68k/init.h
new file mode 100644 (file)
index 0000000..42938ae
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _M68K_INIT_H
+#define _M68K_INIT_H
+
+/* Throwing the initialization code and data out is not supported yet... */
+
+#define        __init
+#define __initdata
+#define __initfunc(__arginit) __arginit
+/* For assembly routines */
+#define __INIT
+#define __FINIT
+#define __INITDATA
+
+#endif
diff --git a/include/asm-mips/init.h b/include/asm-mips/init.h
new file mode 100644 (file)
index 0000000..e4cbd35
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _MIPS_INIT_H
+#define _MIPS_INIT_H
+
+/* Throwing the initialization code and data out is not supported yet... */
+
+#define        __init
+#define __initdata
+#define __initfunc(__arginit) __arginit
+/* For assembly routines */
+#define __INIT
+#define __FINIT
+#define __INITDATA
+
+#endif
diff --git a/include/asm-ppc/init.h b/include/asm-ppc/init.h
new file mode 100644 (file)
index 0000000..82ce44c
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef _PPC_INIT_H
+#define _PPC_INIT_H
+
+/* Throwing the initialization code and data out is not supported yet... */
+
+#define        __init
+#define __initdata
+#define __initfunc(__arginit) __arginit
+/* For assembly routines */
+#define __INIT
+#define __FINIT
+#define __INITDATA
+
+#endif
index 790cff4488fada2a0a8751a95564261aded5c080..f817d0710dba2f5515679158d695a6f926cae154 100644 (file)
  * in linux/version.h, and should only be used by linux/version.c
  */
 
-/* Shouldn't these be defined somewhere in an i386 definition? */
-
-/* Don't touch these, unless you really know what you're doing. */
-#define DEF_INITSEG    0x9000
-#define DEF_SYSSEG     0x1000
-#define DEF_SETUPSEG   0x9020
-#define DEF_SYSSIZE    0x7F00
-
-/* internal svga startup constants */
-#define NORMAL_VGA     0xffff          /* 80x25 mode */
-#define EXTENDED_VGA   0xfffe          /* 80x50 mode */
-#define ASK_VGA                0xfffd          /* ask for it at bootup */
-
 #endif
index c8a7a491a9b765d4c345ec865c2fa53a49785499..462a908083ad5855258746551747a37b2811b9d5 100644 (file)
@@ -7,7 +7,6 @@
 #define asmlinkage
 #endif
 
-#ifdef __ELF__
 #define SYMBOL_NAME_STR(X) #X
 #define SYMBOL_NAME(X) X
 #ifdef __STDC__
 #else
 #define SYMBOL_NAME_LABEL(X) X/**/:
 #endif
-#else
-#define SYMBOL_NAME_STR(X) "_"#X
-#ifdef __STDC__
-#define SYMBOL_NAME(X) _##X
-#define SYMBOL_NAME_LABEL(X) _##X##:
-#else
-#define SYMBOL_NAME(X) _/**/X
-#define SYMBOL_NAME_LABEL(X) _/**/X/**/:
-#endif
-#endif
 
 #if !defined(__i486__) && !defined(__i586__)
-#ifdef __ELF__
 #define __ALIGN .align 4,0x90
 #define __ALIGN_STR ".align 4,0x90"
-#else  /* __ELF__ */
-#define __ALIGN .align 2,0x90
-#define __ALIGN_STR ".align 2,0x90"
-#endif /* __ELF__ */
 #else  /* __i486__/__i586__ */
-#ifdef __ELF__
 #define __ALIGN .align 16,0x90
 #define __ALIGN_STR ".align 16,0x90"
-#else  /* __ELF__ */
-#define __ALIGN .align 4,0x90
-#define __ALIGN_STR ".align 4,0x90"
-#endif /* __ELF__ */
 #endif /* __i486__/__i586__ */
 
 #ifdef __ASSEMBLY__
index 6b930da0c8288994c151e7eef18e68402599ed54..d0304398464e5cdf6c4e3daa127ed98b6e3d73cc 100644 (file)
@@ -104,6 +104,17 @@ struct sched_param {
 
 #ifdef __KERNEL__
 
+#include <asm/spinlock.h>
+
+/*
+ * This serializes "schedule()" and also protects
+ * the run-queue from deletions/modifications (but
+ * _adding_ to the beginning of the run-queue has
+ * a separate lock).
+ */
+extern spinlock_t scheduler_lock;
+extern spinlock_t tasklist_lock;
+
 extern void sched_init(void);
 extern void show_state(void);
 extern void trap_init(void);
@@ -460,11 +471,11 @@ extern inline void poll_wait(struct wait_queue ** wait_address, poll_table * p)
        p->nr++;
 }
 
-#define REMOVE_LINKS(p) do { unsigned long flags; \
-       save_flags(flags) ; cli(); \
+#define REMOVE_LINKS(p) do { \
+       spin_lock(&tasklist_lock); \
        (p)->next_task->prev_task = (p)->prev_task; \
        (p)->prev_task->next_task = (p)->next_task; \
-       restore_flags(flags); \
+       spin_unlock(&tasklist_lock); \
        if ((p)->p_osptr) \
                (p)->p_osptr->p_ysptr = (p)->p_ysptr; \
        if ((p)->p_ysptr) \
@@ -473,13 +484,13 @@ extern inline void poll_wait(struct wait_queue ** wait_address, poll_table * p)
                (p)->p_pptr->p_cptr = (p)->p_osptr; \
        } while (0)
 
-#define SET_LINKS(p) do { unsigned long flags; \
-       save_flags(flags); cli(); \
+#define SET_LINKS(p) do { \
+       spin_lock(&tasklist_lock); \
        (p)->next_task = &init_task; \
        (p)->prev_task = init_task.prev_task; \
        init_task.prev_task->next_task = (p); \
        init_task.prev_task = (p); \
-       restore_flags(flags); \
+       spin_unlock(&tasklist_lock); \
        (p)->p_ysptr = NULL; \
        if (((p)->p_osptr = (p)->p_pptr->p_cptr) != NULL) \
                (p)->p_osptr->p_ysptr = p; \
index 60dcb421ee1200175f50620c63c9fb1408e484e6..17e80e975e070ba40c46f7325610b0014ace2c4e 100644 (file)
@@ -129,9 +129,7 @@ rpc_set_timeout(struct rpc_clnt *clnt, unsigned int retr, unsigned long incr)
 /*
  * Helper function for NFSroot support
  */
-#ifdef CONFIG_ROOT_NFS
 int            rpc_getport_external(struct sockaddr_in *, __u32, __u32, int);
-#endif
 
 #endif /* __KERNEL__ */
 #endif /* _LINUX_SUNRPC_CLNT_H */
index ff5420832ce870471a9a6b59a57bb08e4dfcdade..c6e1527f6fc4448b1567d62e34422dd72c408fa6 100644 (file)
@@ -17,6 +17,9 @@
 /*
  * Modification history timex.h
  *
+ *  9 Jan 97    Adrian Sun
+ *      Shifted LATCH define to allow access to alpha machines.
+ *
  * 26 Sep 94   David L. Mills
  *     Added defines for hybrid phase/frequency-lock loop.
  *
 #define PPS_VALID 120          /* pps signal watchdog max (s) */
 #define MAXGLITCH 30           /* pps signal glitch max (s) */
 
+/* LATCH is used in the interval timer and ftape setup. */
+#define CLOCK_TICK_RATE        1193180 /* Underlying HZ */
+#define LATCH  ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */
+
 #ifndef __alpha__
 /*
  * This definitively is wrong for the Alpha and none of the
  * kernel code seems to reference this anymore.
  */
-#define CLOCK_TICK_RATE        1193180 /* Underlying HZ */
 #define CLOCK_TICK_FACTOR      20      /* Factor of both 1000000 and CLOCK_TICK_RATE */
-#define LATCH  ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */
-
 #define FINETUNE ((((((long)LATCH * HZ - CLOCK_TICK_RATE) << SHIFT_HZ) * \
        (1000000/CLOCK_TICK_FACTOR) / (CLOCK_TICK_RATE/CLOCK_TICK_FACTOR)) \
                << (SHIFT_SCALE-SHIFT_HZ)) / HZ)
index 634e791d539b8d3f7f7bc9da364066aef6b9ae47..add1f30c82c58d38e81211a94b5f7dfed8ff0873 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/slab.h>
 #include <linux/major.h>
 #include <linux/blk.h>
+#include <linux/init.h>
 #ifdef CONFIG_ROOT_NFS
 #include <linux/nfs_fs.h>
 #endif
@@ -256,7 +257,7 @@ extern void dquot_init(void);
 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
 static char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
 
-char *get_options(char *str, int *ints)
+__initfunc(char *get_options(char *str, int *ints))
 {
        char *cur = str;
        int i=1;
@@ -270,7 +271,7 @@ char *get_options(char *str, int *ints)
        return(cur);
 }
 
-static void profile_setup(char *str, int *ints)
+__initfunc(static void profile_setup(char *str, int *ints))
 {
        if (ints[0] > 0)
                prof_shift = (unsigned long) ints[1];
@@ -285,7 +286,7 @@ static void profile_setup(char *str, int *ints)
 struct {
        const char *str;
        void (*setup_func)(char *, int *);
-} bootsetups[] = {
+} bootsetups[] __initdata = {
        { "reserve=", reserve_setup },
        { "profile=", profile_setup },
 #ifdef __SMP__
@@ -502,25 +503,25 @@ struct {
 };
 
 #ifdef CONFIG_BLK_DEV_RAM
-static void ramdisk_start_setup(char *str, int *ints)
+__initfunc(static void ramdisk_start_setup(char *str, int *ints))
 {
    if (ints[0] > 0 && ints[1] >= 0)
       rd_image_start = ints[1];
 }
 
-static void load_ramdisk(char *str, int *ints)
+__initfunc(static void load_ramdisk(char *str, int *ints))
 {
    if (ints[0] > 0 && ints[1] >= 0)
       rd_doload = ints[1] & 1;
 }
 
-static void prompt_ramdisk(char *str, int *ints)
+__initfunc(static void prompt_ramdisk(char *str, int *ints))
 {
    if (ints[0] > 0 && ints[1] >= 0)
       rd_prompt = ints[1] & 1;
 }
 
-static void ramdisk_size(char *str, int *ints)
+__initfunc(static void ramdisk_size(char *str, int *ints))
 {
        if (ints[0] > 0 && ints[1] >= 0)
                rd_size = ints[1];
@@ -528,7 +529,7 @@ static void ramdisk_size(char *str, int *ints)
 
 #endif
 
-static int checksetup(char *line)
+__initfunc(static int checksetup(char *line))
 {
        int i = 0;
        int ints[11];
@@ -560,7 +561,7 @@ unsigned long loops_per_sec = (1<<12);
    better than 1% */
 #define LPS_PREC 8
 
-void calibrate_delay(void)
+__initfunc(void calibrate_delay(void))
 {
        unsigned long ticks, loopbit;
        int lps_precision = LPS_PREC;
@@ -603,7 +604,7 @@ void calibrate_delay(void)
                ((loops_per_sec+2500)/5000) % 100);
 }
 
-static void parse_root_dev(char * line)
+__initfunc(static void parse_root_dev(char * line))
 {
        int base = 0;
        static struct dev_name_struct {
@@ -674,7 +675,7 @@ static void parse_root_dev(char * line)
  * This routine also checks for options meant for the kernel.
  * These options are not given to init - they are for internal kernel use only.
  */
-static void parse_options(char *line)
+__initfunc(static void parse_options(char *line))
 {
        char *next;
        int args, envs;
@@ -782,7 +783,7 @@ extern int cpu_idle(void * unused);
  *     Activate a secondary processor.
  */
  
-asmlinkage void start_secondary(void)
+__initfunc(asmlinkage void start_secondary(void))
 {
        trap_init();
        init_IRQ();
@@ -793,7 +794,7 @@ asmlinkage void start_secondary(void)
 
 
 /* Called by boot processor to activate the rest. */
-static void smp_init(void)
+__initfunc(static void smp_init(void))
 {
        int i, j;
 
@@ -823,7 +824,7 @@ static void smp_init(void)
  *     they are finished.
  */
  
-static void smp_begin(void)
+__initfunc(static void smp_begin(void))
 {
        smp_threads_ready=1;
        smp_commence();
@@ -835,7 +836,7 @@ static void smp_begin(void)
  *     Activate the first processor.
  */
  
-asmlinkage void start_kernel(void)
+__initfunc(asmlinkage void start_kernel(void))
 {
        char * command_line;
 
@@ -947,7 +948,7 @@ asmlinkage void start_kernel(void)
 }
 
 #ifdef CONFIG_BLK_DEV_INITRD
-static int do_linuxrc(void * shell)
+__initfunc(static int do_linuxrc(void * shell))
 {
        static char *argv[] = { "linuxrc", NULL, };
 
@@ -959,7 +960,7 @@ static int do_linuxrc(void * shell)
        return execve(shell, argv, envp_init);
 }
 
-static void no_initrd(char *s,int *ints)
+__initfunc(static void no_initrd(char *s,int *ints))
 {
        mount_initrd = 0;
 }
index 5cb0cb43ac51be0b24c1900d5144fdca80330450..b07bf7522c8dfc350a7bafb95428babc81be8c48 100644 (file)
@@ -16,7 +16,6 @@
  * current-task
  */
 
-#include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
@@ -188,6 +187,10 @@ static inline void move_last_runqueue(struct task_struct * p)
 }
 
 /*
+ * The tasklist_lock protects the linked list of processes
+ * and doesn't need to be interrupt-safe as interrupts never
+ * use the task-list.
+ *
  * The scheduler lock is protecting against multiple entry
  * into the scheduling code, and doesn't need to worry
  * about interrupts (because interrupts cannot call the
@@ -196,6 +199,7 @@ static inline void move_last_runqueue(struct task_struct * p)
  * The run-queue lock locks the parts that actually access
  * and change the run-queues, and have to be interrupt-safe.
  */
+spinlock_t tasklist_lock = SPIN_LOCK_UNLOCKED;
 spinlock_t scheduler_lock = SPIN_LOCK_UNLOCKED;
 static spinlock_t runqueue_lock = SPIN_LOCK_UNLOCKED;
 
@@ -300,7 +304,6 @@ static inline int goodness(struct task_struct * p, struct task_struct * prev, in
  */
 asmlinkage void schedule(void)
 {
-       static int need_recalculate = 0;
        int lock_depth;
        struct task_struct * prev, * next;
        unsigned long timeout;
@@ -384,7 +387,15 @@ asmlinkage void schedule(void)
                                }
                                p = p->next_run;
                        }
-                       need_recalculate = !c;
+
+                       /* Do we need to re-calculate counters? */
+                       if (!c) {
+                               struct task_struct *p;
+                               spin_lock(&tasklist_lock);
+                               for_each_task(p)
+                                       p->counter = (p->counter >> 1) + p->priority;
+                               spin_unlock(&tasklist_lock);
+                       }
                }
        }
 
@@ -410,16 +421,7 @@ asmlinkage void schedule(void)
        }
        spin_unlock(&scheduler_lock);
 
-       if (lock_depth) {
-               reaquire_kernel_lock(prev, smp_processor_id(), lock_depth);
-
-               /* Do we need to re-calculate counters? */
-               if (need_recalculate) {
-                       struct task_struct *p;
-                       for_each_task(p)
-                               p->counter = (p->counter >> 1) + p->priority;
-               }
-       }
+       reaquire_kernel_lock(prev, smp_processor_id(), lock_depth);
 }
 
 #ifndef __alpha__
index dbb8ff1c483a6f5f5e60b4060ebc67b92a28ed7a..cb1a641e7fba130181048b8e61081fbc0e688592 100644 (file)
@@ -9,6 +9,7 @@
  * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
  */
 
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/socket.h>
 #include <linux/kernel.h>