From 546db14ee74118296f425f3b91634fb767d67290 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 27 Jan 2000 01:05:20 +0000 Subject: Merge with Linux 2.3.23. The new bootmem stuff has broken various platforms. At this time I've only verified that IP22 support compiles and IP27 actually works. --- arch/i386/Makefile | 4 - arch/i386/boot/Makefile | 6 +- arch/i386/boot/bootsect.S | 12 +- arch/i386/boot/setup.S | 8 +- arch/i386/boot/video.S | 4 +- arch/i386/config.in | 15 +- arch/i386/defconfig | 24 +- arch/i386/kernel/head.S | 160 ++++++++++- arch/i386/kernel/irq.c | 1 + arch/i386/kernel/pci-i386.c | 54 ++-- arch/i386/kernel/pci-i386.h | 5 +- arch/i386/kernel/pci-pc.c | 77 ++++-- arch/i386/kernel/pci-visws.c | 6 + arch/i386/kernel/setup.c | 252 ++++++++++++------ arch/i386/kernel/smpboot.c | 55 ++-- arch/i386/kernel/traps.c | 8 +- arch/i386/kernel/visws_apic.c | 2 +- arch/i386/kernel/vm86.c | 4 +- arch/i386/lib/Makefile | 2 +- arch/i386/lib/iodebug.c | 19 ++ arch/i386/mm/Makefile | 4 - arch/i386/mm/bigmem.c | 33 --- arch/i386/mm/fault.c | 36 ++- arch/i386/mm/init.c | 607 +++++++++++++++++++++++------------------- arch/i386/mm/ioremap.c | 21 +- arch/i386/vmlinux.lds | 75 ++++++ arch/i386/vmlinux.lds.S | 75 ------ 27 files changed, 966 insertions(+), 603 deletions(-) create mode 100644 arch/i386/lib/iodebug.c delete mode 100644 arch/i386/mm/bigmem.c create mode 100644 arch/i386/vmlinux.lds delete mode 100644 arch/i386/vmlinux.lds.S (limited to 'arch/i386') diff --git a/arch/i386/Makefile b/arch/i386/Makefile index 9978cac9d..37b2371a0 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile @@ -84,9 +84,6 @@ MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot vmlinux: arch/i386/vmlinux.lds -arch/i386/vmlinux.lds: arch/i386/vmlinux.lds.S FORCE - $(CPP) -C -P -imacros $(HPATH)/asm-i386/page_offset.h -Ui386 arch/i386/vmlinux.lds.S >arch/i386/vmlinux.lds - FORCE: ; .PHONY: zImage bzImage compressed zlilo bzlilo zdisk bzdisk install \ @@ -119,7 +116,6 @@ archclean: @$(MAKEBOOT) clean archmrproper: - rm -f arch/i386/vmlinux.lds archdep: @$(MAKEBOOT) dep diff --git a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile index 414e51679..de8cdced8 100644 --- a/arch/i386/boot/Makefile +++ b/arch/i386/boot/Makefile @@ -51,11 +51,11 @@ bootsect.o: bootsect.s bootsect.s: bootsect.S Makefile $(BOOT_INCL) $(CPP) -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@ -bbootsect: bbootsect.o bsetup - $(LD) -Ttext 0x0 -s -oformat binary $< -R bsetup.o -o $@ +bbootsect: bbootsect.o + $(LD) -Ttext 0x0 -s -oformat binary $< -o $@ bbootsect.o: bbootsect.s - $(AS) -o $@ $< + $(AS) --defsym bootsect_kludge=0x220 -o $@ $< bbootsect.s: bootsect.S Makefile $(BOOT_INCL) $(CPP) -D__BIG_KERNEL__ -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@ diff --git a/arch/i386/boot/bootsect.S b/arch/i386/boot/bootsect.S index e7327e1e1..58644810e 100644 --- a/arch/i386/boot/bootsect.S +++ b/arch/i386/boot/bootsect.S @@ -64,12 +64,12 @@ _start: movw %ax, %ds movw $INITSEG, %ax movw %ax, %es - movw $128, %cx + movw $256, %cx subw %si, %si subw %di, %di cld rep - movsl + movsw ljmp $INITSEG, $go # bde - changed 0xff00 to 0x4000 to use debugger at 0x6400 up (bde). We @@ -105,11 +105,11 @@ go: movw $0x4000-12, %di # 0x4000 is an arbitrary value >= movw $0x78, %bx # fs:bx is parameter table address pushw %ds ldsw %fs:(%bx), %si # ds:si is source - movb $3, %cl # copy 12 bytes + movb $6, %cl # copy 12 bytes cld pushw %di # di = 0x4000-12. rep - movsl + movsw popw %di popw %ds movb $36, 0x4(%di) # patch sector count @@ -118,7 +118,7 @@ go: movw $0x4000-12, %di # 0x4000 is an arbitrary value >= # Load the setup-sectors directly after the bootblock. # Note that 'es' is already set up. -# Also, cx = 0 from rep movsl above. +# Also, cx = 0 from rep movsw above. load_setup: xorb %ah, %ah # reset FDC @@ -247,7 +247,7 @@ die: jne die # es must be at 64kB boundary xorw %bx, %bx # bx is starting address within segment rp_read: #ifdef __BIG_KERNEL__ - .word 0x1eff, 0x0220 # lcall *bootsect_kludge in setup.S + lcall bootsect_kludge # in setup.S #else movw %es, %ax subw $SYSSEG, %ax diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S index 859c7248b..9c450bab8 100644 --- a/arch/i386/boot/setup.S +++ b/arch/i386/boot/setup.S @@ -209,14 +209,14 @@ bad_sig: addw $SYSSEG, %bx movw %bx, %cs:start_sys_seg # Move rest of setup code/data to here - movw $2048, %di # four sectors loaded by LILO + movw $4096, %di # four sectors loaded by LILO subw %si, %si movw %cs, %ax # aka SETUPSEG movw %ax, %es movw $SYSSEG, %ax movw %ax, %ds rep - movsl + movsw movw %cs, %ax # aka SETUPSEG movw %ax, %ds cmpw $SIG1, setup_sig1 @@ -532,9 +532,9 @@ do_move: addw $0x100, %bx subw %di, %di subw %si, %si - movw $0x400, %cx + movw $0x800, %cx rep - movsl + movsw cmpw %bp, %bx # assume start_sys_seg > 0x200, # so we will perhaps read one # page more than needed, but diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S index 3052b6838..77d22bef1 100644 --- a/arch/i386/boot/video.S +++ b/arch/i386/boot/video.S @@ -1152,7 +1152,7 @@ dosvga: lodsw pushw %es movw $0xc000, %bx movw %bx, %es - call ax # Call test routine + call *%ax # Call test routine popw %es popw %di popw %si @@ -1741,7 +1741,7 @@ even7: movb $0x0c, %al cmpb %bh, %al jne isnot - movb $VIDEO_FIRST_V7>>8, $svga_prefix # Use special mode switching + movb $VIDEO_FIRST_V7>>8, svga_prefix # Use special mode switching ret video7_md: diff --git a/arch/i386/config.in b/arch/i386/config.in index 9d373d1ed..b8f081e65 100644 --- a/arch/i386/config.in +++ b/arch/i386/config.in @@ -42,9 +42,17 @@ if [ "$CONFIG_MK7" = "y" ]; then define_bool CONFIG_X86_USE_3DNOW y fi -choice 'Maximum Physical Memory' \ - "1GB CONFIG_1GB \ - 2GB CONFIG_2GB" 1GB +choice 'High Memory Support' \ + "off CONFIG_NOHIGHMEM \ + 4GB CONFIG_HIGHMEM4G \ + 64GB CONFIG_HIGHMEM64G" off +if [ "$CONFIG_HIGHMEM4G" = "y" ]; then + define_bool CONFIG_HIGHMEM y +fi +if [ "$CONFIG_HIGHMEM64G" = "y" ]; then + define_bool CONFIG_HIGHMEM y + define_bool CONFIG_X86_PAE y +fi bool 'Math emulation' CONFIG_MATH_EMULATION bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR @@ -63,7 +71,6 @@ endmenu mainmenu_option next_comment comment 'General setup' -bool 'BIGMEM support' CONFIG_BIGMEM bool 'Networking support' CONFIG_NET bool 'SGI Visual Workstation support' CONFIG_VISWS if [ "$CONFIG_VISWS" = "y" ]; then diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 49137cda4..8b6370667 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -24,8 +24,9 @@ CONFIG_X86_BSWAP=y CONFIG_X86_POPAD_OK=y CONFIG_X86_TSC=y CONFIG_X86_GOOD_APIC=y -CONFIG_1GB=y -# CONFIG_2GB is not set +CONFIG_NOHIGHMEM=y +# CONFIG_HIGHMEM4G is not set +# CONFIG_HIGHMEM64G is not set # CONFIG_MATH_EMULATION is not set # CONFIG_MTRR is not set CONFIG_SMP=y @@ -40,7 +41,6 @@ CONFIG_MODULES=y # # General setup # -# CONFIG_BIGMEM is not set CONFIG_NET=y # CONFIG_VISWS is not set CONFIG_X86_IO_APIC=y @@ -54,10 +54,12 @@ CONFIG_PCI_DIRECT=y # CONFIG_MCA is not set # -# PCMCIA/Cardbus support +# PCMCIA/CardBus support # CONFIG_PCMCIA=y CONFIG_CARDBUS=y +CONFIG_I82365=y +# CONFIG_TCIC is not set CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y @@ -111,7 +113,7 @@ CONFIG_BLK_DEV_IDEPCI=y # CONFIG_BLK_DEV_OFFBOARD is not set # CONFIG_BLK_DEV_AEC6210 is not set CONFIG_BLK_DEV_PIIX=y -# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_PIIX_TUNING is not set # CONFIG_IDE_CHIPSETS is not set # CONFIG_BLK_CPQ_DA is not set @@ -284,11 +286,19 @@ CONFIG_EEXPRESS_PRO100=y # CONFIG_WAN is not set # -# PCMCIA network devices +# PCMCIA network device support # -CONFIG_PCMCIA_PCNET=y +CONFIG_NET_PCMCIA=y # CONFIG_PCMCIA_3C589 is not set +# CONFIG_PCMCIA_3C574 is not set +# CONFIG_PCMCIA_FMVJ18X is not set +CONFIG_PCMCIA_PCNET=y +# CONFIG_PCMCIA_NMCLAN is not set +# CONFIG_PCMCIA_SMC91C92 is not set +# CONFIG_PCMCIA_XIRC2PS is not set CONFIG_PCMCIA_RAYCS=y +# CONFIG_PCMCIA_NETWAVE is not set +# CONFIG_PCMCIA_WAVELAN is not set CONFIG_PCMCIA_NETCARD=y # diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S index f1aa50586..423308aae 100644 --- a/arch/i386/kernel/head.S +++ b/arch/i386/kernel/head.S @@ -367,11 +367,13 @@ SYMBOL_NAME(gdt): .org 0x1000 ENTRY(swapper_pg_dir) .long 0x00102007 - .fill __USER_PGD_PTRS-1,4,0 - /* default: 767 entries */ + .long 0x00103007 + .fill BOOT_USER_PGD_PTRS-2,4,0 + /* default: 766 entries */ .long 0x00102007 - /* default: 255 entries */ - .fill __KERNEL_PGD_PTRS-1,4,0 + .long 0x00103007 + /* default: 254 entries */ + .fill BOOT_KERNEL_PGD_PTRS-2,4,0 /* * The page tables are initialized to only 4MB here - the final page @@ -509,16 +511,156 @@ ENTRY(pg0) .long 0x3f0007,0x3f1007,0x3f2007,0x3f3007,0x3f4007,0x3f5007,0x3f6007,0x3f7007 .long 0x3f8007,0x3f9007,0x3fa007,0x3fb007,0x3fc007,0x3fd007,0x3fe007,0x3ff007 -.org 0x3000 -ENTRY(empty_bad_page) - +ENTRY(pg1) + .long 0x400007,0x001007,0x002007,0x003007,0x004007,0x005007,0x006007,0x007007 + .long 0x408007,0x009007,0x00a007,0x00b007,0x00c007,0x00d007,0x00e007,0x00f007 + .long 0x410007,0x011007,0x012007,0x013007,0x014007,0x015007,0x016007,0x017007 + .long 0x418007,0x019007,0x01a007,0x01b007,0x01c007,0x01d007,0x01e007,0x01f007 + .long 0x420007,0x021007,0x022007,0x023007,0x024007,0x025007,0x026007,0x027007 + .long 0x428007,0x029007,0x02a007,0x02b007,0x02c007,0x02d007,0x02e007,0x02f007 + .long 0x430007,0x031007,0x032007,0x033007,0x034007,0x035007,0x036007,0x037007 + .long 0x438007,0x039007,0x03a007,0x03b007,0x03c007,0x03d007,0x03e007,0x03f007 + .long 0x440007,0x041007,0x042007,0x043007,0x044007,0x045007,0x046007,0x047007 + .long 0x448007,0x049007,0x04a007,0x04b007,0x04c007,0x04d007,0x04e007,0x04f007 + .long 0x450007,0x051007,0x052007,0x053007,0x054007,0x055007,0x056007,0x057007 + .long 0x458007,0x059007,0x05a007,0x05b007,0x05c007,0x05d007,0x05e007,0x05f007 + .long 0x460007,0x061007,0x062007,0x063007,0x064007,0x065007,0x066007,0x067007 + .long 0x468007,0x069007,0x06a007,0x06b007,0x06c007,0x06d007,0x06e007,0x06f007 + .long 0x470007,0x071007,0x072007,0x073007,0x074007,0x075007,0x076007,0x077007 + .long 0x478007,0x079007,0x07a007,0x07b007,0x07c007,0x07d007,0x07e007,0x07f007 + .long 0x480007,0x081007,0x082007,0x083007,0x084007,0x085007,0x086007,0x087007 + .long 0x488007,0x089007,0x08a007,0x08b007,0x08c007,0x08d007,0x08e007,0x08f007 + .long 0x490007,0x091007,0x092007,0x093007,0x094007,0x095007,0x096007,0x097007 + .long 0x498007,0x099007,0x09a007,0x09b007,0x09c007,0x09d007,0x09e007,0x09f007 + .long 0x4a0007,0x0a1007,0x0a2007,0x0a3007,0x0a4007,0x0a5007,0x0a6007,0x0a7007 + .long 0x4a8007,0x0a9007,0x0aa007,0x0ab007,0x0ac007,0x0ad007,0x0ae007,0x0af007 + .long 0x4b0007,0x0b1007,0x0b2007,0x0b3007,0x0b4007,0x0b5007,0x0b6007,0x0b7007 + .long 0x4b8007,0x0b9007,0x0ba007,0x0bb007,0x0bc007,0x0bd007,0x0be007,0x0bf007 + .long 0x4c0007,0x0c1007,0x0c2007,0x0c3007,0x0c4007,0x0c5007,0x0c6007,0x0c7007 + .long 0x4c8007,0x0c9007,0x0ca007,0x0cb007,0x0cc007,0x0cd007,0x0ce007,0x0cf007 + .long 0x4d0007,0x0d1007,0x0d2007,0x0d3007,0x0d4007,0x0d5007,0x0d6007,0x0d7007 + .long 0x4d8007,0x0d9007,0x0da007,0x0db007,0x0dc007,0x0dd007,0x0de007,0x0df007 + .long 0x4e0007,0x0e1007,0x0e2007,0x0e3007,0x0e4007,0x0e5007,0x0e6007,0x0e7007 + .long 0x4e8007,0x0e9007,0x0ea007,0x0eb007,0x0ec007,0x0ed007,0x0ee007,0x0ef007 + .long 0x4f0007,0x0f1007,0x0f2007,0x0f3007,0x0f4007,0x0f5007,0x0f6007,0x0f7007 + .long 0x4f8007,0x0f9007,0x0fa007,0x0fb007,0x0fc007,0x0fd007,0x0fe007,0x0ff007 + .long 0x500007,0x001007,0x002007,0x003007,0x004007,0x005007,0x006007,0x007007 + .long 0x508007,0x009007,0x00a007,0x00b007,0x00c007,0x00d007,0x00e007,0x00f007 + .long 0x510007,0x011007,0x012007,0x013007,0x014007,0x015007,0x016007,0x017007 + .long 0x518007,0x019007,0x01a007,0x01b007,0x01c007,0x01d007,0x01e007,0x01f007 + .long 0x520007,0x021007,0x022007,0x023007,0x024007,0x025007,0x026007,0x027007 + .long 0x528007,0x029007,0x02a007,0x02b007,0x02c007,0x02d007,0x02e007,0x02f007 + .long 0x530007,0x031007,0x032007,0x033007,0x034007,0x035007,0x036007,0x037007 + .long 0x538007,0x039007,0x03a007,0x03b007,0x03c007,0x03d007,0x03e007,0x03f007 + .long 0x540007,0x041007,0x042007,0x043007,0x044007,0x045007,0x046007,0x047007 + .long 0x548007,0x049007,0x04a007,0x04b007,0x04c007,0x04d007,0x04e007,0x04f007 + .long 0x550007,0x051007,0x052007,0x053007,0x054007,0x055007,0x056007,0x057007 + .long 0x558007,0x059007,0x05a007,0x05b007,0x05c007,0x05d007,0x05e007,0x05f007 + .long 0x560007,0x061007,0x062007,0x063007,0x064007,0x065007,0x066007,0x067007 + .long 0x568007,0x069007,0x06a007,0x06b007,0x06c007,0x06d007,0x06e007,0x06f007 + .long 0x570007,0x071007,0x072007,0x073007,0x074007,0x075007,0x076007,0x077007 + .long 0x578007,0x079007,0x07a007,0x07b007,0x07c007,0x07d007,0x07e007,0x07f007 + .long 0x580007,0x081007,0x082007,0x083007,0x084007,0x085007,0x086007,0x087007 + .long 0x588007,0x089007,0x08a007,0x08b007,0x08c007,0x08d007,0x08e007,0x08f007 + .long 0x590007,0x091007,0x092007,0x093007,0x094007,0x095007,0x096007,0x097007 + .long 0x598007,0x099007,0x09a007,0x09b007,0x09c007,0x09d007,0x09e007,0x09f007 + .long 0x5a0007,0x0a1007,0x0a2007,0x0a3007,0x0a4007,0x0a5007,0x0a6007,0x0a7007 + .long 0x5a8007,0x0a9007,0x0aa007,0x0ab007,0x0ac007,0x0ad007,0x0ae007,0x0af007 + .long 0x5b0007,0x0b1007,0x0b2007,0x0b3007,0x0b4007,0x0b5007,0x0b6007,0x0b7007 + .long 0x5b8007,0x0b9007,0x0ba007,0x0bb007,0x0bc007,0x0bd007,0x0be007,0x0bf007 + .long 0x5c0007,0x0c1007,0x0c2007,0x0c3007,0x0c4007,0x0c5007,0x0c6007,0x0c7007 + .long 0x5c8007,0x0c9007,0x0ca007,0x0cb007,0x0cc007,0x0cd007,0x0ce007,0x0cf007 + .long 0x5d0007,0x0d1007,0x0d2007,0x0d3007,0x0d4007,0x0d5007,0x0d6007,0x0d7007 + .long 0x5d8007,0x0d9007,0x0da007,0x0db007,0x0dc007,0x0dd007,0x0de007,0x0df007 + .long 0x5e0007,0x0e1007,0x0e2007,0x0e3007,0x0e4007,0x0e5007,0x0e6007,0x0e7007 + .long 0x5e8007,0x0e9007,0x0ea007,0x0eb007,0x0ec007,0x0ed007,0x0ee007,0x0ef007 + .long 0x5f0007,0x0f1007,0x0f2007,0x0f3007,0x0f4007,0x0f5007,0x0f6007,0x0f7007 + .long 0x5f8007,0x0f9007,0x0fa007,0x0fb007,0x0fc007,0x0fd007,0x0fe007,0x0ff007 + .long 0x600007,0x001007,0x002007,0x003007,0x004007,0x005007,0x006007,0x007007 + .long 0x608007,0x009007,0x00a007,0x00b007,0x00c007,0x00d007,0x00e007,0x00f007 + .long 0x610007,0x011007,0x012007,0x013007,0x014007,0x015007,0x016007,0x017007 + .long 0x618007,0x019007,0x01a007,0x01b007,0x01c007,0x01d007,0x01e007,0x01f007 + .long 0x620007,0x021007,0x022007,0x023007,0x024007,0x025007,0x026007,0x027007 + .long 0x628007,0x029007,0x02a007,0x02b007,0x02c007,0x02d007,0x02e007,0x02f007 + .long 0x630007,0x031007,0x032007,0x033007,0x034007,0x035007,0x036007,0x037007 + .long 0x638007,0x039007,0x03a007,0x03b007,0x03c007,0x03d007,0x03e007,0x03f007 + .long 0x640007,0x041007,0x042007,0x043007,0x044007,0x045007,0x046007,0x047007 + .long 0x648007,0x049007,0x04a007,0x04b007,0x04c007,0x04d007,0x04e007,0x04f007 + .long 0x650007,0x051007,0x052007,0x053007,0x054007,0x055007,0x056007,0x057007 + .long 0x658007,0x059007,0x05a007,0x05b007,0x05c007,0x05d007,0x05e007,0x05f007 + .long 0x660007,0x061007,0x062007,0x063007,0x064007,0x065007,0x066007,0x067007 + .long 0x668007,0x069007,0x06a007,0x06b007,0x06c007,0x06d007,0x06e007,0x06f007 + .long 0x670007,0x071007,0x072007,0x073007,0x074007,0x075007,0x076007,0x077007 + .long 0x678007,0x079007,0x07a007,0x07b007,0x07c007,0x07d007,0x07e007,0x07f007 + .long 0x680007,0x081007,0x082007,0x083007,0x084007,0x085007,0x086007,0x087007 + .long 0x688007,0x089007,0x08a007,0x08b007,0x08c007,0x08d007,0x08e007,0x08f007 + .long 0x690007,0x091007,0x092007,0x093007,0x094007,0x095007,0x096007,0x097007 + .long 0x698007,0x099007,0x09a007,0x09b007,0x09c007,0x09d007,0x09e007,0x09f007 + .long 0x6a0007,0x0a1007,0x0a2007,0x0a3007,0x0a4007,0x0a5007,0x0a6007,0x0a7007 + .long 0x6a8007,0x0a9007,0x0aa007,0x0ab007,0x0ac007,0x0ad007,0x0ae007,0x0af007 + .long 0x6b0007,0x0b1007,0x0b2007,0x0b3007,0x0b4007,0x0b5007,0x0b6007,0x0b7007 + .long 0x6b8007,0x0b9007,0x0ba007,0x0bb007,0x0bc007,0x0bd007,0x0be007,0x0bf007 + .long 0x6c0007,0x0c1007,0x0c2007,0x0c3007,0x0c4007,0x0c5007,0x0c6007,0x0c7007 + .long 0x6c8007,0x0c9007,0x0ca007,0x0cb007,0x0cc007,0x0cd007,0x0ce007,0x0cf007 + .long 0x6d0007,0x0d1007,0x0d2007,0x0d3007,0x0d4007,0x0d5007,0x0d6007,0x0d7007 + .long 0x6d8007,0x0d9007,0x0da007,0x0db007,0x0dc007,0x0dd007,0x0de007,0x0df007 + .long 0x6e0007,0x0e1007,0x0e2007,0x0e3007,0x0e4007,0x0e5007,0x0e6007,0x0e7007 + .long 0x6e8007,0x0e9007,0x0ea007,0x0eb007,0x0ec007,0x0ed007,0x0ee007,0x0ef007 + .long 0x6f0007,0x0f1007,0x0f2007,0x0f3007,0x0f4007,0x0f5007,0x0f6007,0x0f7007 + .long 0x6f8007,0x0f9007,0x0fa007,0x0fb007,0x0fc007,0x0fd007,0x0fe007,0x0ff007 + .long 0x700007,0x001007,0x002007,0x003007,0x004007,0x005007,0x006007,0x007007 + .long 0x708007,0x009007,0x00a007,0x00b007,0x00c007,0x00d007,0x00e007,0x00f007 + .long 0x710007,0x011007,0x012007,0x013007,0x014007,0x015007,0x016007,0x017007 + .long 0x718007,0x019007,0x01a007,0x01b007,0x01c007,0x01d007,0x01e007,0x01f007 + .long 0x720007,0x021007,0x022007,0x023007,0x024007,0x025007,0x026007,0x027007 + .long 0x728007,0x029007,0x02a007,0x02b007,0x02c007,0x02d007,0x02e007,0x02f007 + .long 0x730007,0x031007,0x032007,0x033007,0x034007,0x035007,0x036007,0x037007 + .long 0x738007,0x039007,0x03a007,0x03b007,0x03c007,0x03d007,0x03e007,0x03f007 + .long 0x740007,0x041007,0x042007,0x043007,0x044007,0x045007,0x046007,0x047007 + .long 0x748007,0x049007,0x04a007,0x04b007,0x04c007,0x04d007,0x04e007,0x04f007 + .long 0x750007,0x051007,0x052007,0x053007,0x054007,0x055007,0x056007,0x057007 + .long 0x758007,0x059007,0x05a007,0x05b007,0x05c007,0x05d007,0x05e007,0x05f007 + .long 0x760007,0x061007,0x062007,0x063007,0x064007,0x065007,0x066007,0x067007 + .long 0x768007,0x069007,0x06a007,0x06b007,0x06c007,0x06d007,0x06e007,0x06f007 + .long 0x770007,0x071007,0x072007,0x073007,0x074007,0x075007,0x076007,0x077007 + .long 0x778007,0x079007,0x07a007,0x07b007,0x07c007,0x07d007,0x07e007,0x07f007 + .long 0x780007,0x081007,0x082007,0x083007,0x084007,0x085007,0x086007,0x087007 + .long 0x788007,0x089007,0x08a007,0x08b007,0x08c007,0x08d007,0x08e007,0x08f007 + .long 0x790007,0x091007,0x092007,0x093007,0x094007,0x095007,0x096007,0x097007 + .long 0x798007,0x099007,0x09a007,0x09b007,0x09c007,0x09d007,0x09e007,0x09f007 + .long 0x7a0007,0x0a1007,0x0a2007,0x0a3007,0x0a4007,0x0a5007,0x0a6007,0x0a7007 + .long 0x7a8007,0x0a9007,0x0aa007,0x0ab007,0x0ac007,0x0ad007,0x0ae007,0x0af007 + .long 0x7b0007,0x0b1007,0x0b2007,0x0b3007,0x0b4007,0x0b5007,0x0b6007,0x0b7007 + .long 0x7b8007,0x0b9007,0x0ba007,0x0bb007,0x0bc007,0x0bd007,0x0be007,0x0bf007 + .long 0x7c0007,0x0c1007,0x0c2007,0x0c3007,0x0c4007,0x0c5007,0x0c6007,0x0c7007 + .long 0x7c8007,0x0c9007,0x0ca007,0x0cb007,0x0cc007,0x0cd007,0x0ce007,0x0cf007 + .long 0x7d0007,0x0d1007,0x0d2007,0x0d3007,0x0d4007,0x0d5007,0x0d6007,0x0d7007 + .long 0x7d8007,0x0d9007,0x0da007,0x0db007,0x0dc007,0x0dd007,0x0de007,0x0df007 + .long 0x7e0007,0x0e1007,0x0e2007,0x0e3007,0x0e4007,0x0e5007,0x0e6007,0x0e7007 + .long 0x7e8007,0x0e9007,0x0ea007,0x0eb007,0x0ec007,0x0ed007,0x0ee007,0x0ef007 + .long 0x7f0007,0x0f1007,0x0f2007,0x0f3007,0x0f4007,0x0f5007,0x0f6007,0x0f7007 + .long 0x7f8007,0x0f9007,0x0fa007,0x0fb007,0x0fc007,0x0fd007,0x0fe007,0x0ff007 .org 0x4000 -ENTRY(empty_bad_page_table) +ENTRY(empty_zero_page) .org 0x5000 -ENTRY(empty_zero_page) +ENTRY(empty_bad_page) .org 0x6000 +ENTRY(empty_bad_pte_table) + +#if CONFIG_X86_PAE + + .org 0x7000 + ENTRY(empty_bad_pmd_table) + + .org 0x8000 + +#else + + .org 0x7000 + +#endif /* * This starts the data section. Note that the above is all diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c index 8ec329287..75659aac4 100644 --- a/arch/i386/kernel/irq.c +++ b/arch/i386/kernel/irq.c @@ -20,6 +20,7 @@ * Naturally it's not a 1:1 relation, but there are similarities. */ +#include #include #include #include diff --git a/arch/i386/kernel/pci-i386.c b/arch/i386/kernel/pci-i386.c index af362611d..8e609ec36 100644 --- a/arch/i386/kernel/pci-i386.c +++ b/arch/i386/kernel/pci-i386.c @@ -177,7 +177,7 @@ static int __init pcibios_assign_resource(struct pci_dev *dev, int i) * (4) Assign new addresses to resources which were either * not configured at all or misconfigured. If explicitly * requested by the user, configure expansion ROM address - * as well. Finally enable the I/O and Memory bits. + * as well. */ static void __init pcibios_allocate_bus_resources(struct pci_bus *bus) @@ -252,21 +252,18 @@ static void __init pcibios_allocate_resources(int pass) static void __init pcibios_assign_resources(void) { struct pci_dev *dev; - u16 cmd, old_cmd; int idx; - int fault = 0; struct resource *r; for(dev=pci_devices; dev; dev=dev->next) { - pci_read_config_word(dev, PCI_COMMAND, &cmd); - old_cmd = cmd; for(idx=0; idx<6; idx++) { r = &dev->resource[idx]; if (((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && idx < 4) || - ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO))) + ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO)) || + !dev->class || (dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) /* * Don't touch IDE controllers and I/O ports of video cards! - * Neither enable anything in their command registers. + * Also avoid classless devices and host bridges. */ continue; if (!r->start && r->end) { @@ -275,24 +272,9 @@ static void __init pcibios_assign_resources(void) * the BIOS forgot to do so or because we have decided the old * address was unusable for some reason. */ - if (pcibios_assign_resource(dev, idx) < 0) - fault = 1; - } - if (r->flags & IORESOURCE_IO) - cmd |= PCI_COMMAND_IO; - if (r->flags & IORESOURCE_MEM) - cmd |= PCI_COMMAND_MEMORY; - } - - if (cmd != old_cmd) { - if (fault) - printk("PCI: Not enabling device %s because of resource collisions\n", dev->slot_name); - else { - printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd); - pci_write_config_word(dev, PCI_COMMAND, cmd); + pcibios_assign_resource(dev, idx); } } - if (pci_probe & PCI_ASSIGN_ROMS) { r = &dev->resource[PCI_ROM_RESOURCE]; r->end -= r->start; @@ -310,3 +292,29 @@ void __init pcibios_resource_survey(void) pcibios_allocate_resources(1); pcibios_assign_resources(); } + +int pcibios_enable_resources(struct pci_dev *dev) +{ + u16 cmd, old_cmd; + int idx; + struct resource *r; + + pci_read_config_word(dev, PCI_COMMAND, &cmd); + old_cmd = cmd; + for(idx=0; idx<6; idx++) { + r = &dev->resource[idx]; + if (!r->start && r->end) { + printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name); + return -EINVAL; + } + if (r->flags & IORESOURCE_IO) + cmd |= PCI_COMMAND_IO; + if (r->flags & IORESOURCE_MEM) + cmd |= PCI_COMMAND_MEMORY; + } + if (cmd != old_cmd) { + printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd); + } + return 0; +} diff --git a/arch/i386/kernel/pci-i386.h b/arch/i386/kernel/pci-i386.h index 41ac2b856..1be988b6c 100644 --- a/arch/i386/kernel/pci-i386.h +++ b/arch/i386/kernel/pci-i386.h @@ -18,12 +18,13 @@ #define PCI_NO_SORT 0x100 #define PCI_BIOS_SORT 0x200 #define PCI_NO_CHECKS 0x400 -#define PCI_NO_PEER_FIXUP 0x800 +#define PCI_PEER_FIXUP 0x800 #define PCI_ASSIGN_ROMS 0x1000 -#define PCI_NO_IRQ_SCAN 0x2000 +#define PCI_BIOS_IRQ_SCAN 0x2000 extern unsigned int pci_probe; /* pci-i386.c */ void pcibios_resource_survey(void); +int pcibios_enable_resources(struct pci_dev *); diff --git a/arch/i386/kernel/pci-pc.c b/arch/i386/kernel/pci-pc.c index 8ce187d3f..61d13af55 100644 --- a/arch/i386/kernel/pci-pc.c +++ b/arch/i386/kernel/pci-pc.c @@ -688,7 +688,7 @@ static struct irq_routing_table * __init pcibios_get_irq_routing_table(void) struct irq_routing_table *rt; int ret, map; - if (pci_probe & PCI_NO_IRQ_SCAN) + if (!(pci_probe & PCI_BIOS_IRQ_SCAN)) return NULL; pcibios_irq_page = __get_free_page(GFP_KERNEL); if (!pcibios_irq_page) @@ -868,7 +868,30 @@ static void __init pci_fixup_i450nx(struct pci_dev *d) if (suba < subb) pci_scan_bus(suba+1, pci_root->ops, NULL); /* Bus B */ } - pci_probe |= PCI_NO_PEER_FIXUP; +} + +static void __init pci_fixup_rcc(struct pci_dev *d) +{ + /* + * RCC host bridges -- Find and scan all secondary buses. + * Register 0x44 contains first, 0x45 last bus number routed there. + */ + u8 busno; + pci_read_config_byte(d, 0x44, &busno); + printk("PCI: RCC host bridge: secondary bus %02x\n", busno); + pci_scan_bus(busno, pci_root->ops, NULL); +} + +static void __init pci_fixup_compaq(struct pci_dev *d) +{ + /* + * Compaq host bridges -- Find and scan all secondary buses. + * This time registers 0xc8 and 0xc9. + */ + u8 busno; + pci_read_config_byte(d, 0xc8, &busno); + printk("PCI: Compaq host bridge: secondary bus %02x\n", busno); + pci_scan_bus(busno, pci_root->ops, NULL); } static void __init pci_fixup_umc_ide(struct pci_dev *d) @@ -905,6 +928,9 @@ static void __init pci_fixup_ide_bases(struct pci_dev *d) struct pci_fixup pcibios_fixups[] = { { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, pci_fixup_i450nx }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_RCC, PCI_DEVICE_ID_RCC_HE, pci_fixup_rcc }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_RCC, PCI_DEVICE_ID_RCC_LE, pci_fixup_rcc }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_6010, pci_fixup_compaq }, { PCI_FIXUP_HEADER, PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886BF, pci_fixup_umc_ide }, { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases }, { 0 } @@ -919,6 +945,8 @@ extern int skip_ioapic_setup; #define PIRQ_SIGNATURE (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24)) #define PIRQ_VERSION 0x0100 +static struct irq_routing_table *pirq_table; + /* * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. */ @@ -974,7 +1002,6 @@ static void __init pcibios_irq_peer_trick(struct irq_routing_table *rt) */ if (busmap[i] && pci_scan_bus(i, pci_root->ops, NULL)) printk("PCI: Discovered primary peer bus %02x [IRQ]\n", i); - pci_probe |= PCI_NO_PEER_FIXUP; } /* @@ -982,7 +1009,7 @@ static void __init pcibios_irq_peer_trick(struct irq_routing_table *rt) * table, but unfortunately we have to know the interrupt router chip. */ -static char * __init pcibios_lookup_irq(struct pci_dev *dev, struct irq_routing_table *rt, int pin) +static char *pcibios_lookup_irq(struct pci_dev *dev, struct irq_routing_table *rt, int pin, int assign) { struct irq_info *q; struct pci_dev *router; @@ -1012,9 +1039,9 @@ static char * __init pcibios_lookup_irq(struct pci_dev *dev, struct irq_routing_ return NULL; } DBG(" -> PIRQ %02x, mask %04x", pirq, mask); - if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) + if (!assign || (dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) newirq = 0; - else for(newirq = 15; newirq && !(mask & (1 << newirq)); newirq--) + else for(newirq = 13; newirq && !(mask & (1 << newirq)); newirq--) ; if (!(router = pci_find_slot(rt->rtr_bus, rt->rtr_devfn))) { DBG(" -> router not found\n"); @@ -1068,7 +1095,7 @@ static void __init pcibios_fixup_irqs(void) struct pci_dev *dev; u8 pin; - rtable = pcibios_find_irq_routing_table(); + rtable = pirq_table = pcibios_find_irq_routing_table(); #ifdef CONFIG_PCI_BIOS if (!rtable && pci_bios_present) rtable = pcibios_get_irq_routing_table(); @@ -1106,7 +1133,7 @@ static void __init pcibios_fixup_irqs(void) dev->irq = irq; } } - rtable = NULL; /* Avoid IRQ assignment below */ + pirq_table = NULL; /* Avoid automatic IRQ assignment */ } #endif /* @@ -1114,10 +1141,10 @@ static void __init pcibios_fixup_irqs(void) */ if (dev->irq >= NR_IRQS) dev->irq = 0; - if (pin && !dev->irq && rtable && rtable->version) { - char *msg = pcibios_lookup_irq(dev, rtable, pin); + if (pin && !dev->irq && pirq_table) { + char *msg = pcibios_lookup_irq(dev, pirq_table, pin, 0); if (msg) - printk("PCI: Assigned IRQ %d to device %s [%s]\n", dev->irq, dev->slot_name, msg); + printk("PCI: Found IRQ %d for device %s [%s]\n", dev->irq, dev->slot_name, msg); } } @@ -1173,7 +1200,7 @@ void __init pcibios_init(void) pci_scan_bus(0, ops, NULL); pcibios_fixup_irqs(); - if (!(pci_probe & PCI_NO_PEER_FIXUP)) + if (pci_probe & PCI_PEER_FIXUP) pcibios_fixup_peer_bridges(); pcibios_resource_survey(); @@ -1199,8 +1226,8 @@ char * __init pcibios_setup(char *str) } else if (!strcmp(str, "nosort")) { pci_probe |= PCI_NO_SORT; return NULL; - } else if (!strcmp(str, "noirq")) { - pci_probe |= PCI_NO_IRQ_SCAN; + } else if (!strcmp(str, "biosirq")) { + pci_probe |= PCI_BIOS_IRQ_SCAN; return NULL; } #endif @@ -1214,8 +1241,8 @@ char * __init pcibios_setup(char *str) return NULL; } #endif - else if (!strcmp(str, "nopeer")) { - pci_probe |= PCI_NO_PEER_FIXUP; + else if (!strcmp(str, "peer")) { + pci_probe |= PCI_PEER_FIXUP; return NULL; } else if (!strcmp(str, "rom")) { pci_probe |= PCI_ASSIGN_ROMS; @@ -1223,3 +1250,21 @@ char * __init pcibios_setup(char *str) } return str; } + +int pcibios_enable_device(struct pci_dev *dev) +{ + int err; + + if ((err = pcibios_enable_resources(dev)) < 0) + return err; + if (!dev->irq && pirq_table) { + u8 pin; + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + if (pin) { + char *msg = pcibios_lookup_irq(dev, pirq_table, pin, 1); + if (msg) + printk("PCI: Assigned IRQ %d to device %s [%s]\n", dev->irq, dev->slot_name, msg); + } + } + return 0; +} diff --git a/arch/i386/kernel/pci-visws.c b/arch/i386/kernel/pci-visws.c index 31a767a22..8a954ce8b 100644 --- a/arch/i386/kernel/pci-visws.c +++ b/arch/i386/kernel/pci-visws.c @@ -14,6 +14,7 @@ #include #include +#include #include "pci-i386.h" @@ -129,3 +130,8 @@ char * __init pcibios_setup(char *str) { return str; } + +int pcibios_enable_device(struct pci_dev *dev) +{ + return pcibios_enable_resources(dev); +} diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 734cfca65..31c77bb1d 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -54,7 +54,8 @@ #ifdef CONFIG_BLK_DEV_RAM #include #endif -#include +#include +#include #include #include #include @@ -401,12 +402,15 @@ void __init add_memory_region(unsigned long start, } /* add_memory_region */ -#define LOWMEMSIZE() ((*(unsigned short *)__va(0x413)) * 1024) - +/* + * Do NOT EVER look at the BIOS memory size location. + * It does not work on many machines. + */ +#define LOWMEMSIZE() (0x9f000) void __init setup_memory_region(void) { -#define E820_DEBUG 0 +#define E820_DEBUG 1 #ifdef E820_DEBUG int i; #endif @@ -432,9 +436,8 @@ void __init setup_memory_region(void) memcpy(e820.map, E820_MAP, e820.nr_map * sizeof e820.map[0]); #ifdef E820_DEBUG for (i=0; i < e820.nr_map; i++) { - printk("e820: %ld @ %08lx ", - (unsigned long)(e820.map[i].size), - (unsigned long)(e820.map[i].addr)); + printk("e820: %08x @ %08x ", (int)e820.map[i].size, + (int)e820.map[i].addr); switch (e820.map[i].type) { case E820_RAM: printk("(usable)\n"); break; @@ -464,48 +467,11 @@ void __init setup_memory_region(void) } /* setup_memory_region */ -void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * memory_end_p) +static inline void parse_mem_cmdline (char ** cmdline_p) { - unsigned long high_pfn, max_pfn; char c = ' ', *to = command_line, *from = COMMAND_LINE; int len = 0; - int i; - int usermem=0; - -#ifdef CONFIG_VISWS - visws_get_board_type_and_rev(); -#endif - - ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV); - drive_info = DRIVE_INFO; - screen_info = SCREEN_INFO; - apm_bios_info = APM_BIOS_INFO; - if( SYS_DESC_TABLE.length != 0 ) { - MCA_bus = SYS_DESC_TABLE.table[3] &0x2; - machine_id = SYS_DESC_TABLE.table[0]; - machine_submodel_id = SYS_DESC_TABLE.table[1]; - BIOS_revision = SYS_DESC_TABLE.table[2]; - } - aux_device_present = AUX_DEVICE_INFO; - -#ifdef CONFIG_BLK_DEV_RAM - rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK; - rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0); - rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0); -#endif - setup_memory_region(); - - if (!MOUNT_ROOT_RDONLY) - root_mountflags &= ~MS_RDONLY; - init_mm.start_code = (unsigned long) &_text; - init_mm.end_code = (unsigned long) &_etext; - init_mm.end_data = (unsigned long) &_edata; - init_mm.brk = (unsigned long) &_end; - - code_resource.start = virt_to_bus(&_text); - code_resource.end = virt_to_bus(&_etext)-1; - data_resource.start = virt_to_bus(&_etext); - data_resource.end = virt_to_bus(&_edata)-1; + int usermem = 0; /* Save unparsed command line copy for /proc/cmdline */ memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); @@ -519,8 +485,9 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigne * "mem=XXX[KkmM]@XXX[KkmM]" defines a memory region from * to +, overriding the bios size. */ - if (c == ' ' && *(const unsigned long *)from == *(const unsigned long *)"mem=") { - if (to != command_line) to--; + if (c == ' ' && !memcmp(from, "mem=", 4)) { + if (to != command_line) + to--; if (!memcmp(from+4, "nopentium", 9)) { from += 9+4; boot_cpu_data.x86_capability &= ~X86_FEATURE_PSE; @@ -542,7 +509,7 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigne } mem_size = memparse(from+4, &from); if (*from == '@') - start_at = memparse(from+1,&from); + start_at = memparse(from+1, &from); else { start_at = HIGH_MEMORY; mem_size -= HIGH_MEMORY; @@ -559,54 +526,166 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigne } *to = '\0'; *cmdline_p = command_line; +} - /* Find the highest page frame number we have available */ - max_pfn = 0; - for (i=0; i < e820.nr_map; i++) { - /* RAM? */ - if (e820.map[i].type == E820_RAM) { - unsigned long end_pfn = (e820.map[i].addr + e820.map[i].size) >> PAGE_SHIFT; +void __init setup_arch(char **cmdline_p) +{ + unsigned long bootmap_size; + unsigned long start_pfn, max_pfn, max_low_pfn; + int i; - if (end_pfn > max_pfn) - max_pfn = end_pfn; - } +#ifdef CONFIG_VISWS + visws_get_board_type_and_rev(); +#endif + + ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV); + drive_info = DRIVE_INFO; + screen_info = SCREEN_INFO; + apm_bios_info = APM_BIOS_INFO; + if( SYS_DESC_TABLE.length != 0 ) { + MCA_bus = SYS_DESC_TABLE.table[3] &0x2; + machine_id = SYS_DESC_TABLE.table[0]; + machine_submodel_id = SYS_DESC_TABLE.table[1]; + BIOS_revision = SYS_DESC_TABLE.table[2]; } + aux_device_present = AUX_DEVICE_INFO; -/* - * We can only allocate a limited amount of direct-mapped memory - */ -#define VMALLOC_RESERVE (128 << 20) /* 128MB for vmalloc and initrd */ -#define MAXMEM ((unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE)) -#define MAXMEM_PFN (MAXMEM >> PAGE_SHIFT) +#ifdef CONFIG_BLK_DEV_RAM + rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK; + rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0); + rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0); +#endif + setup_memory_region(); + + if (!MOUNT_ROOT_RDONLY) + root_mountflags &= ~MS_RDONLY; + init_mm.start_code = (unsigned long) &_text; + init_mm.end_code = (unsigned long) &_etext; + init_mm.end_data = (unsigned long) &_edata; + init_mm.brk = (unsigned long) &_end; - high_pfn = MAXMEM_PFN; - if (max_pfn < high_pfn) - high_pfn = max_pfn; + code_resource.start = virt_to_bus(&_text); + code_resource.end = virt_to_bus(&_etext)-1; + data_resource.start = virt_to_bus(&_etext); + data_resource.end = virt_to_bus(&_edata)-1; + + parse_mem_cmdline(cmdline_p); + +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) +#define PFN_PHYS(x) ((x) << PAGE_SHIFT) /* - * But the bigmem stuff may be able to use more of it - * (but currently only up to about 4GB) + * 128MB for vmalloc and initrd */ -#ifdef CONFIG_BIGMEM - #define MAXBIGMEM ((unsigned long)(~(VMALLOC_RESERVE-1))) - #define MAXBIGMEM_PFN (MAXBIGMEM >> PAGE_SHIFT) - if (max_pfn > MAX_PFN) - max_pfn = MAX_PFN; - -/* When debugging, make half of "normal" memory be BIGMEM memory instead */ -#ifdef BIGMEM_DEBUG - high_pfn >>= 1; -#endif +#define VMALLOC_RESERVE (unsigned long)(128 << 20) +#define MAXMEM (unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE) +#define MAXMEM_PFN PFN_DOWN(MAXMEM) + + /* + * partially used pages are not usable - thus + * we are rounding upwards: + */ + start_pfn = PFN_UP(__pa(&_end)); - bigmem_start = high_pfn << PAGE_SHIFT; - bigmem_end = max_pfn << PAGE_SHIFT; - printk(KERN_NOTICE "%ldMB BIGMEM available.\n", (bigmem_end-bigmem_start) >> 20); + /* + * Find the highest page frame number we have available + */ + max_pfn = 0; + for (i = 0; i < e820.nr_map; i++) { + unsigned long curr_pfn; + /* RAM? */ + if (e820.map[i].type != E820_RAM) + continue; + curr_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size); + if (curr_pfn > max_pfn) + max_pfn = curr_pfn; + } + + /* + * Determine low and high memory ranges: + */ + max_low_pfn = max_pfn; + if (max_low_pfn > MAXMEM_PFN) + max_low_pfn = MAXMEM_PFN; + +#ifdef CONFIG_HIGHMEM + highstart_pfn = highend_pfn = max_pfn; + if (max_pfn > MAXMEM_PFN) { + highstart_pfn = MAXMEM_PFN; + highend_pfn = max_pfn; + printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", + pages_to_mb(highend_pfn - highstart_pfn)); + } #endif + /* + * Initialize the boot-time allocator (with low memory only): + */ + bootmap_size = init_bootmem(start_pfn, max_low_pfn); + + /* + * FIXME: what about high memory? + */ + ram_resources[1].end = PFN_PHYS(max_low_pfn); + + /* + * Register fully available low RAM pages with the bootmem allocator. + */ + for (i = 0; i < e820.nr_map; i++) { + unsigned long curr_pfn, last_pfn, size; + /* + * Reserve usable low memory + */ + if (e820.map[i].type != E820_RAM) + continue; + /* + * We are rounding up the start address of usable memory: + */ + curr_pfn = PFN_UP(e820.map[i].addr); + if (curr_pfn >= max_low_pfn) + continue; + /* + * ... and at the end of the usable range downwards: + */ + last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size); - ram_resources[1].end = (high_pfn << PAGE_SHIFT)-1; + if (last_pfn > max_low_pfn) + last_pfn = max_low_pfn; - *memory_start_p = (unsigned long) &_end; - *memory_end_p = PAGE_OFFSET + (high_pfn << PAGE_SHIFT); + /* + * .. finally, did all the rounding and playing + * around just make the area go away? + */ + if (last_pfn <= curr_pfn) + continue; + + size = last_pfn - curr_pfn; + free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); + } + /* + * Reserve the bootmem bitmap itself as well. We do this in two + * steps (first step was init_bootmem()) because this catches + * the (very unlikely) case of us accidentally initializing the + * bootmem allocator with an invalid RAM area. + */ + reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(start_pfn) + + bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY)); + + /* + * reserve physical page 0 - it's a special BIOS page on many boxes, + * enabling clean reboots, SMP operation, laptop functions. + */ + reserve_bootmem(0, PAGE_SIZE); + +#ifdef __SMP__ + /* + * But first pinch a few for the stack/trampoline stuff + * FIXME: Don't need the extra page at 4K, but need to fix + * trampoline before removing it. (see the GDT stuff) + */ + reserve_bootmem(PAGE_SIZE, PAGE_SIZE); + smp_alloc_memory(); /* AP processor realmode stacks in low memory*/ +#endif #ifdef __SMP__ /* @@ -616,10 +695,11 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigne #endif #ifdef CONFIG_BLK_DEV_INITRD +// FIXME needs to do the new bootmem alloc stuff if (LOADER_TYPE) { initrd_start = INITRD_START ? INITRD_START + PAGE_OFFSET : 0; initrd_end = initrd_start+INITRD_SIZE; - if (initrd_end > memory_end) { + if (initrd_end > (max_low_pfn << PAGE_SHIFT)) { printk("initrd extends beyond end of memory " "(0x%08lx > 0x%08lx)\ndisabling initrd\n", initrd_end,memory_end); diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index 46335ee8f..4386e8dd0 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -630,12 +631,15 @@ static unsigned long __init setup_trampoline(void) * We are called very early to get the low memory for the * SMP bootup trampoline page. */ -unsigned long __init smp_alloc_memory(unsigned long mem_base) +void __init smp_alloc_memory(void) { - if (virt_to_phys((void *)mem_base) >= 0x9F000) + trampoline_base = (void *) alloc_bootmem_low_pages(PAGE_SIZE); + /* + * Has to be in very low memory so we can execute + * real-mode AP code. + */ + if (__pa(trampoline_base) >= 0x9F000) BUG(); - trampoline_base = (void *)mem_base; - return mem_base + PAGE_SIZE; } /* @@ -804,11 +808,10 @@ void __init setup_local_APIC(void) apic_write(APIC_DFR, value); } -unsigned long __init init_smp_mappings(unsigned long memory_start) +void __init init_smp_mappings(void) { unsigned long apic_phys; - memory_start = PAGE_ALIGN(memory_start); if (smp_found_config) { apic_phys = mp_lapic_addr; } else { @@ -818,11 +821,10 @@ unsigned long __init init_smp_mappings(unsigned long memory_start) * could use the real zero-page, but it's safer * this way if some buggy code writes to this page ... */ - apic_phys = __pa(memory_start); - memset((void *)memory_start, 0, PAGE_SIZE); - memory_start += PAGE_SIZE; + apic_phys = __pa(alloc_bootmem_pages(PAGE_SIZE)); + memset((void *)apic_phys, 0, PAGE_SIZE); } - set_fixmap(FIX_APIC_BASE,apic_phys); + set_fixmap(FIX_APIC_BASE, apic_phys); dprintk("mapped APIC to %08lx (%08lx)\n", APIC_BASE, apic_phys); #ifdef CONFIG_X86_IO_APIC @@ -834,9 +836,8 @@ unsigned long __init init_smp_mappings(unsigned long memory_start) if (smp_found_config) { ioapic_phys = mp_ioapics[i].mpc_apicaddr; } else { - ioapic_phys = __pa(memory_start); - memset((void *)memory_start, 0, PAGE_SIZE); - memory_start += PAGE_SIZE; + ioapic_phys = __pa(alloc_bootmem_pages(PAGE_SIZE)); + memset((void *)ioapic_phys, 0, PAGE_SIZE); } set_fixmap(idx,ioapic_phys); dprintk("mapped IOAPIC to %08lx (%08lx)\n", @@ -845,8 +846,6 @@ unsigned long __init init_smp_mappings(unsigned long memory_start) } } #endif - - return memory_start; } /* @@ -1112,6 +1111,12 @@ int __init start_secondary(void *unused) smp_callin(); while (!atomic_read(&smp_commenced)) /* nothing */ ; + /* + * low-memory mappings have been cleared, flush them from + * the local TLBs too. + */ + local_flush_tlb(); + return cpu_idle(); } @@ -1153,7 +1158,6 @@ static int __init fork_by_hand(void) static void __init do_boot_cpu(int i) { unsigned long cfg; - pgd_t maincfg; struct task_struct *idle; unsigned long send_status, accept_status; int timeout, num_starts, j; @@ -1207,9 +1211,6 @@ static void __init do_boot_cpu(int i) *((volatile unsigned short *) phys_to_virt(0x467)) = start_eip & 0xf; dprintk("3.\n"); - maincfg=swapper_pg_dir[0]; - ((unsigned long *)swapper_pg_dir)[0]=0x102007; - /* * Be paranoid about clearing APIC errors. */ @@ -1367,9 +1368,6 @@ static void __init do_boot_cpu(int i) cpucount--; } - swapper_pg_dir[0]=maincfg; - local_flush_tlb(); - /* mark "stuck" area as not stuck */ *((volatile unsigned long *)phys_to_virt(8192)) = 0; } @@ -1567,14 +1565,9 @@ void __init smp_boot_cpus(void) #ifndef CONFIG_VISWS { - unsigned long cfg; - /* * Install writable page 0 entry to set BIOS data area. */ - cfg = pg0[0]; - /* writeable, present, addr 0 */ - pg0[0] = _PAGE_RW | _PAGE_PRESENT | 0; local_flush_tlb(); /* @@ -1584,12 +1577,6 @@ void __init smp_boot_cpus(void) CMOS_WRITE(0, 0xf); *((volatile long *) phys_to_virt(0x467)) = 0; - - /* - * Restore old page 0 entry. - */ - pg0[0] = cfg; - local_flush_tlb(); } #endif @@ -1646,5 +1633,7 @@ smp_done: */ if (cpu_has_tsc && cpucount) synchronize_tsc_bp(); + + zap_low_mappings(); } diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index ebd1cd002..f66f2363c 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -581,6 +581,7 @@ asmlinkage void math_emulate(long arg) #endif /* CONFIG_MATH_EMULATION */ +#ifndef CONFIG_M686 void __init trap_init_f00f_bug(void) { unsigned long page; @@ -596,8 +597,8 @@ void __init trap_init_f00f_bug(void) pgd = pgd_offset(&init_mm, page); pmd = pmd_offset(pgd, page); pte = pte_offset(pmd, page); - free_page(pte_page(*pte)); - *pte = mk_pte(&idt_table, PAGE_KERNEL_RO); + __free_page(pte_page(*pte)); + *pte = mk_pte_phys(__pa(&idt_table), PAGE_KERNEL_RO); local_flush_tlb(); /* @@ -608,6 +609,7 @@ void __init trap_init_f00f_bug(void) idt = (struct desc_struct *)page; __asm__ __volatile__("lidt %0": "=m" (idt_descr)); } +#endif #define _set_gate(gate_addr,type,dpl,addr) \ do { \ @@ -772,7 +774,7 @@ cobalt_init(void) #endif void __init trap_init(void) { - if (readl(0x0FFFD9) == 'E' + ('I'<<8) + ('S'<<16) + ('A'<<24)) + if (isa_readl(0x0FFFD9) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) EISA_bus = 1; set_trap_gate(0,÷_error); diff --git a/arch/i386/kernel/visws_apic.c b/arch/i386/kernel/visws_apic.c index de79fe61e..6c767d0eb 100644 --- a/arch/i386/kernel/visws_apic.c +++ b/arch/i386/kernel/visws_apic.c @@ -37,7 +37,7 @@ #include -#include "irq.h" +#include /* * This is the PIIX4-based 8259 that is wired up indirectly to Cobalt diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c index 65dd7e9da..3fd5262ac 100644 --- a/arch/i386/kernel/vm86.c +++ b/arch/i386/kernel/vm86.c @@ -102,7 +102,7 @@ static void mark_screen_rdonly(struct task_struct * tsk) if (pgd_none(*pgd)) return; if (pgd_bad(*pgd)) { - printk("vm86: bad pgd entry [%p]:%08lx\n", pgd, pgd_val(*pgd)); + pgd_ERROR(*pgd); pgd_clear(pgd); return; } @@ -110,7 +110,7 @@ static void mark_screen_rdonly(struct task_struct * tsk) if (pmd_none(*pmd)) return; if (pmd_bad(*pmd)) { - printk("vm86: bad pmd entry [%p]:%08lx\n", pmd, pmd_val(*pmd)); + pmd_ERROR(*pmd); pmd_clear(pmd); return; } diff --git a/arch/i386/lib/Makefile b/arch/i386/lib/Makefile index 3f7bef4aa..5c824c08c 100644 --- a/arch/i386/lib/Makefile +++ b/arch/i386/lib/Makefile @@ -7,7 +7,7 @@ L_TARGET = lib.a L_OBJS = checksum.o old-checksum.o delay.o \ - usercopy.o getuser.o putuser.o + usercopy.o getuser.o putuser.o iodebug.o ifdef CONFIG_X86_USE_3DNOW L_OBJS += mmx.o diff --git a/arch/i386/lib/iodebug.c b/arch/i386/lib/iodebug.c new file mode 100644 index 000000000..701a07fe7 --- /dev/null +++ b/arch/i386/lib/iodebug.c @@ -0,0 +1,19 @@ +#include + +void * __io_virt_debug(unsigned long x, const char *file, int line) +{ + if (x < PAGE_OFFSET) { + printk("io mapaddr 0x%05lx not valid at %s:%d!\n", x, file, line); + return __va(x); + } + return (void *)x; +} + +unsigned long __io_phys_debug(unsigned long x, const char *file, int line) +{ + if (x < PAGE_OFFSET) { + printk("io mapaddr 0x%05lx not valid at %s:%d!\n", x, file, line); + return x; + } + return __pa(x); +} diff --git a/arch/i386/mm/Makefile b/arch/i386/mm/Makefile index d60bc1969..cee7d4e6d 100644 --- a/arch/i386/mm/Makefile +++ b/arch/i386/mm/Makefile @@ -10,8 +10,4 @@ O_TARGET := mm.o O_OBJS := init.o fault.o ioremap.o extable.o -ifeq ($(CONFIG_BIGMEM),y) -O_OBJS += bigmem.o -endif - include $(TOPDIR)/Rules.make diff --git a/arch/i386/mm/bigmem.c b/arch/i386/mm/bigmem.c deleted file mode 100644 index 8da077927..000000000 --- a/arch/i386/mm/bigmem.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * BIGMEM IA32 code and variables. - * - * (C) 1999 Andrea Arcangeli, SuSE GmbH, andrea@suse.de - * Gerhard Wichert, Siemens AG, Gerhard.Wichert@pdb.siemens.de - */ - -#include -#include - -unsigned long bigmem_start, bigmem_end; - -/* NOTE: fixmap_init alloc all the fixmap pagetables contigous on the - physical space so we can cache the place of the first one and move - around without checking the pgd every time. */ -pte_t *kmap_pte; -pgprot_t kmap_prot; - -#define kmap_get_fixmap_pte(vaddr) \ - pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)) - -void __init kmap_init(void) -{ - unsigned long kmap_vstart; - - /* cache the first kmap pte */ - kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); - kmap_pte = kmap_get_fixmap_pte(kmap_vstart); - - kmap_prot = PAGE_KERNEL; - if (boot_cpu_data.x86_capability & X86_FEATURE_PGE) - pgprot_val(kmap_prot) |= _PAGE_GLOBAL; -} diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c index 1f7879005..b2a98859b 100644 --- a/arch/i386/mm/fault.c +++ b/arch/i386/mm/fault.c @@ -76,6 +76,31 @@ bad_area: return 0; } +static inline void handle_wp_test (void) +{ + const unsigned long vaddr = PAGE_OFFSET; + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + + /* + * make it read/writable temporarily, so that the fault + * can be handled. + */ + pgd = swapper_pg_dir + __pgd_offset(vaddr); + pmd = pmd_offset(pgd, vaddr); + pte = pte_offset(pmd, vaddr); + *pte = mk_pte_phys(0, PAGE_KERNEL); + local_flush_tlb(); + + boot_cpu_data.wp_works_ok = 1; + /* + * Beware: Black magic here. The printk is needed here to flush + * CPU state on certain buggy processors. + */ + printk("Ok"); +} + asmlinkage void do_invalid_op(struct pt_regs *, unsigned long); extern unsigned long idt; @@ -226,15 +251,8 @@ no_context: * First we check if it was the bootup rw-test, though.. */ if (boot_cpu_data.wp_works_ok < 0 && - address == PAGE_OFFSET && (error_code & 1)) { - boot_cpu_data.wp_works_ok = 1; - pg0[0] = pte_val(mk_pte(PAGE_OFFSET, PAGE_KERNEL)); - local_flush_tlb(); - /* - * Beware: Black magic here. The printk is needed here to flush - * CPU state on certain buggy processors. - */ - printk("Ok"); + address == PAGE_OFFSET && (error_code & 1)) { + handle_wp_test(); return; } diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c index b1140f892..d2089fbd0 100644 --- a/arch/i386/mm/init.c +++ b/arch/i386/mm/init.c @@ -22,7 +22,9 @@ #ifdef CONFIG_BLK_DEV_INITRD #include #endif -#include +#include +#include +#include #include #include @@ -32,22 +34,81 @@ #include #include -static unsigned long totalram = 0; -static unsigned long totalbig = 0; +unsigned long highstart_pfn, highend_pfn; +static unsigned long totalram_pages = 0; +static unsigned long totalhigh_pages = 0; extern void show_net_buffers(void); -extern unsigned long init_smp_mappings(unsigned long); -void __bad_pte_kernel(pmd_t *pmd) +/* + * BAD_PAGE is the page that is used for page faults when linux + * is out-of-memory. Older versions of linux just did a + * do_exit(), but using this instead means there is less risk + * for a process dying in kernel mode, possibly leaving an inode + * unused etc.. + * + * BAD_PAGETABLE is the accompanying page-table: it is initialized + * to point to BAD_PAGE entries. + * + * ZERO_PAGE is a special page that is used for zero-initialized + * data and COW. + */ + +/* + * These are allocated in head.S so that we get proper page alignment. + * If you change the size of these then change head.S as well. + */ +extern char empty_bad_page[PAGE_SIZE]; +#if CONFIG_X86_PAE +extern pmd_t empty_bad_pmd_table[PTRS_PER_PMD]; +#endif +extern pte_t empty_bad_pte_table[PTRS_PER_PTE]; + +/* + * We init them before every return and make them writable-shared. + * This guarantees we get out of the kernel in some more or less sane + * way. + */ +#if CONFIG_X86_PAE +static pmd_t * get_bad_pmd_table(void) { - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); - pmd_val(*pmd) = _KERNPG_TABLE + __pa(BAD_PAGETABLE); + pmd_t v; + int i; + + pmd_val(v) = _PAGE_TABLE + __pa(empty_bad_pte_table); + + for (i = 0; i < PAGE_SIZE/sizeof(pmd_t); i++) + empty_bad_pmd_table[i] = v; + + return empty_bad_pmd_table; } +#endif -void __bad_pte(pmd_t *pmd) +static pte_t * get_bad_pte_table(void) { - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); - pmd_val(*pmd) = _PAGE_TABLE + __pa(BAD_PAGETABLE); + pte_t v; + int i; + + v = pte_mkdirty(mk_pte_phys(__pa(empty_bad_page), PAGE_SHARED)); + + for (i = 0; i < PAGE_SIZE/sizeof(pte_t); i++) + empty_bad_pte_table[i] = v; + + return empty_bad_pte_table; +} + + + +void __handle_bad_pmd(pmd_t *pmd) +{ + pmd_ERROR(*pmd); + pmd_val(*pmd) = _PAGE_TABLE + __pa(get_bad_pte_table()); +} + +void __handle_bad_pmd_kernel(pmd_t *pmd) +{ + pmd_ERROR(*pmd); + pmd_val(*pmd) = _KERNPG_TABLE + __pa(get_bad_pte_table()); } pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset) @@ -57,16 +118,16 @@ pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset) pte = (pte_t *) __get_free_page(GFP_KERNEL); if (pmd_none(*pmd)) { if (pte) { - clear_page((unsigned long)pte); + clear_page(pte); pmd_val(*pmd) = _KERNPG_TABLE + __pa(pte); return pte + offset; } - pmd_val(*pmd) = _KERNPG_TABLE + __pa(BAD_PAGETABLE); + pmd_val(*pmd) = _KERNPG_TABLE + __pa(get_bad_pte_table()); return NULL; } free_page((unsigned long)pte); if (pmd_bad(*pmd)) { - __bad_pte_kernel(pmd); + __handle_bad_pmd_kernel(pmd); return NULL; } return (pte_t *) pmd_page(*pmd) + offset; @@ -79,19 +140,19 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset) pte = (unsigned long) __get_free_page(GFP_KERNEL); if (pmd_none(*pmd)) { if (pte) { - clear_page(pte); + clear_page((void *)pte); pmd_val(*pmd) = _PAGE_TABLE + __pa(pte); - return (pte_t *)(pte + offset); + return (pte_t *)pte + offset; } - pmd_val(*pmd) = _PAGE_TABLE + __pa(BAD_PAGETABLE); + pmd_val(*pmd) = _PAGE_TABLE + __pa(get_bad_pte_table()); return NULL; } free_page(pte); if (pmd_bad(*pmd)) { - __bad_pte(pmd); + __handle_bad_pmd(pmd); return NULL; } - return (pte_t *) (pmd_page(*pmd) + offset); + return (pte_t *) pmd_page(*pmd) + offset; } int do_check_pgt_cache(int low, int high) @@ -110,52 +171,36 @@ int do_check_pgt_cache(int low, int high) return freed; } -/* - * BAD_PAGE is the page that is used for page faults when linux - * is out-of-memory. Older versions of linux just did a - * do_exit(), but using this instead means there is less risk - * for a process dying in kernel mode, possibly leaving an inode - * unused etc.. - * - * BAD_PAGETABLE is the accompanying page-table: it is initialized - * to point to BAD_PAGE entries. - * - * ZERO_PAGE is a special page that is used for zero-initialized - * data and COW. - */ -pte_t * __bad_pagetable(void) -{ - extern char empty_bad_page_table[PAGE_SIZE]; - int d0, d1; - - __asm__ __volatile__("cld ; rep ; stosl" - : "=&D" (d0), "=&c" (d1) - : "a" (pte_val(BAD_PAGE)), - "0" ((long) empty_bad_page_table), - "1" (PAGE_SIZE/4) - : "memory"); - return (pte_t *) empty_bad_page_table; -} +/* NOTE: fixmap_init alloc all the fixmap pagetables contigous on the + physical space so we can cache the place of the first one and move + around without checking the pgd every time. */ + +#if CONFIG_HIGHMEM +pte_t *kmap_pte; +pgprot_t kmap_prot; -pte_t __bad_page(void) +#define kmap_get_fixmap_pte(vaddr) \ + pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)) + +void __init kmap_init(void) { - extern char empty_bad_page[PAGE_SIZE]; - int d0, d1; - - __asm__ __volatile__("cld ; rep ; stosl" - : "=&D" (d0), "=&c" (d1) - : "a" (0), - "0" ((long) empty_bad_page), - "1" (PAGE_SIZE/4) - : "memory"); - return pte_mkdirty(mk_pte((unsigned long) empty_bad_page, PAGE_SHARED)); + unsigned long kmap_vstart; + + /* cache the first kmap pte */ + kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); + kmap_pte = kmap_get_fixmap_pte(kmap_vstart); + + kmap_prot = PAGE_KERNEL; + if (boot_cpu_data.x86_capability & X86_FEATURE_PGE) + pgprot_val(kmap_prot) |= _PAGE_GLOBAL; } +#endif void show_mem(void) { - int i,free = 0,total = 0,reserved = 0; + int i,free = 0, total = 0, reserved = 0; int shared = 0, cached = 0; - int bigmem = 0; + int highmem = 0; printk("Mem-info:\n"); show_free_areas(); @@ -163,8 +208,8 @@ void show_mem(void) i = max_mapnr; while (i-- > 0) { total++; - if (PageBIGMEM(mem_map+i)) - bigmem++; + if (PageHighMem(mem_map+i)) + highmem++; if (PageReserved(mem_map+i)) reserved++; else if (PageSwapCache(mem_map+i)) @@ -174,59 +219,42 @@ void show_mem(void) else shared += page_count(mem_map+i) - 1; } - printk("%d pages of RAM\n",total); - printk("%d pages of BIGMEM\n",bigmem); + printk("%d pages of RAM\n", total); + printk("%d pages of HIGHMEM\n",highmem); printk("%d reserved pages\n",reserved); printk("%d pages shared\n",shared); printk("%d pages swap cached\n",cached); printk("%ld pages in page table cache\n",pgtable_cache_size); + show_buffers(); #ifdef CONFIG_NET show_net_buffers(); #endif } -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; -/* - * allocate page table(s) for compile-time fixed mappings - */ -static unsigned long __init fixmap_init(unsigned long start_mem) -{ - pgd_t * pg_dir; - unsigned int idx; - unsigned long address; - - start_mem = PAGE_ALIGN(start_mem); - - for (idx=1; idx <= __end_of_fixed_addresses; idx += PTRS_PER_PTE) - { - address = __fix_to_virt(__end_of_fixed_addresses-idx); - pg_dir = swapper_pg_dir + (address >> PGDIR_SHIFT); - memset((void *)start_mem, 0, PAGE_SIZE); - pgd_val(*pg_dir) = _PAGE_TABLE | __pa(start_mem); - start_mem += PAGE_SIZE; - } - - return start_mem; -} - static void set_pte_phys (unsigned long vaddr, unsigned long phys) { pgprot_t prot; - pte_t * pte; + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; - pte = pte_offset(pmd_offset(pgd_offset_k(vaddr), vaddr), vaddr); + pgd = swapper_pg_dir + __pgd_offset(vaddr); + pmd = pmd_offset(pgd, vaddr); + pte = pte_offset(pmd, vaddr); prot = PAGE_KERNEL; if (boot_cpu_data.x86_capability & X86_FEATURE_PGE) pgprot_val(prot) |= _PAGE_GLOBAL; set_pte(pte, mk_pte_phys(phys, prot)); - local_flush_tlb(); + /* + * It's enough to flush this one mapping. + */ + __flush_tlb_one(vaddr); } void set_fixmap (enum fixed_addresses idx, unsigned long phys) @@ -240,6 +268,123 @@ void set_fixmap (enum fixed_addresses idx, unsigned long phys) set_pte_phys (address,phys); } +static void __init pagetable_init(void) +{ + pgd_t *pgd, *pgd_base; + pmd_t *pmd; + pte_t *pte; + int i, j, k; + unsigned long vaddr; + unsigned long end = (unsigned long)__va(max_low_pfn*PAGE_SIZE); + + pgd_base = swapper_pg_dir; + + vaddr = PAGE_OFFSET; + i = __pgd_offset(vaddr); + pgd = pgd_base + i; + + for (; (i < PTRS_PER_PGD) && (vaddr <= end); pgd++, i++) { + vaddr = i*PGDIR_SIZE; +#if CONFIG_X86_PAE + pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); + memset((void*)pmd, 0, PAGE_SIZE); + pgd_val(*pgd) = __pa(pmd) + 0x1; +#else + pmd = (pmd_t *)pgd; +#endif + if (pmd != pmd_offset(pgd, 0)) + BUG(); + for (j = 0; (j < PTRS_PER_PMD) && (vaddr <= end); pmd++, j++) { + vaddr = i*PGDIR_SIZE + j*PMD_SIZE; + if (cpu_has_pse) { + unsigned long __pe; + + set_in_cr4(X86_CR4_PSE); + boot_cpu_data.wp_works_ok = 1; + __pe = _KERNPG_TABLE + _PAGE_PSE + __pa(vaddr); + /* Make it "global" too if supported */ + if (cpu_has_pge) { + set_in_cr4(X86_CR4_PGE); + __pe += _PAGE_GLOBAL; + } + pmd_val(*pmd) = __pe; + continue; + } + + pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); + memset((void*)pte, 0, PAGE_SIZE); + pmd_val(*pmd) = _KERNPG_TABLE + __pa(pte); + + if (pte != pte_offset(pmd, 0)) + BUG(); + + for (k = 0; + (k < PTRS_PER_PTE) && (vaddr <= end); + pte++, k++) { + vaddr = i*PGDIR_SIZE + j*PMD_SIZE + k*PAGE_SIZE; + *pte = mk_pte_phys(__pa(vaddr), PAGE_KERNEL); + } + } + } + + /* + * Fixed mappings, only the page table structure has to be + * created - mappings will be set by set_fixmap(): + */ + + vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; + i = __pgd_offset(vaddr); + j = __pmd_offset(vaddr); + pgd = pgd_base + i; + + for ( ; (i < PTRS_PER_PGD) && vaddr; pgd++, i++) { +#if CONFIG_X86_PAE + if (pgd_none(*pgd)) { + pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); + memset((void*)pmd, 0, PAGE_SIZE); + pgd_val(*pgd) = __pa(pmd) + 0x1; + if (pmd != pmd_offset(pgd, vaddr)) + BUG(); + } + pmd = pmd_offset(pgd, vaddr); +#else + pmd = (pmd_t *)pgd; +#endif + for (; (j < PTRS_PER_PMD) && vaddr; pmd++, j++) { + if (pmd_none(*pmd)) { + pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); + memset((void*)pte, 0, PAGE_SIZE); + pmd_val(*pmd) = _KERNPG_TABLE + __pa(pte); + if (pte != pte_offset(pmd, 0)) + BUG(); + } + vaddr += PMD_SIZE; + } + j = 0; + } + +#if CONFIG_X86_PAE + /* + * Add low memory identity-mappings - SMP needs it when + * starting up on an AP from real-mode. In the non-PAE + * case we already have these mappings through head.S. + * All user-space mappings are explicitly cleared after + * SMP startup. + */ + pgd_base[0] = pgd_base[USER_PTRS_PER_PGD]; +#endif +} + +void __init zap_low_mappings (void) +{ + int i; + /* + * Zap initial low-memory mappings: + */ + for (i = 0; i < USER_PTRS_PER_PGD; i++) + pgd_clear(swapper_pg_dir + i); +} + /* * paging_init() sets up the page tables - note that the first 4MB are * already mapped by head.S. @@ -247,89 +392,36 @@ void set_fixmap (enum fixed_addresses idx, unsigned long phys) * 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 __init paging_init(unsigned long start_mem, unsigned long end_mem) +void __init paging_init(void) { - pgd_t * pg_dir; - pte_t * pg_table; - unsigned long tmp; - unsigned long address; + pagetable_init(); -/* - * Physical page 0 is special; it's not touched by Linux since BIOS - * and SMM (for laptops with [34]86/SL chips) may need it. It is read - * and write protected to detect null pointer references in the - * kernel. - * It may also hold the MP configuration table when we are booting SMP. - */ - start_mem = PAGE_ALIGN(start_mem); - address = PAGE_OFFSET; - pg_dir = swapper_pg_dir; - /* unmap the original low memory mappings */ - pgd_val(pg_dir[0]) = 0; - - /* Map whole memory from PAGE_OFFSET */ - pg_dir += USER_PGD_PTRS; - while (address < end_mem) { - /* - * If we're running on a Pentium CPU, we can use the 4MB - * page tables. - * - * The page tables we create span up to the next 4MB - * virtual memory boundary, but that's OK as we won't - * use that memory anyway. - */ - if (boot_cpu_data.x86_capability & X86_FEATURE_PSE) { - unsigned long __pe; - - set_in_cr4(X86_CR4_PSE); - boot_cpu_data.wp_works_ok = 1; - __pe = _KERNPG_TABLE + _PAGE_4M + __pa(address); - /* Make it "global" too if supported */ - if (boot_cpu_data.x86_capability & X86_FEATURE_PGE) { - set_in_cr4(X86_CR4_PGE); - __pe += _PAGE_GLOBAL; - } - pgd_val(*pg_dir) = __pe; - pg_dir++; - address += 4*1024*1024; - continue; - } + __asm__( "movl %%ecx,%%cr3\n" ::"c"(__pa(swapper_pg_dir))); - /* - * We're on a [34]86, use normal page tables. - * pg_table is physical at this point - */ - pg_table = (pte_t *) (PAGE_MASK & pgd_val(*pg_dir)); - if (!pg_table) { - pg_table = (pte_t *) __pa(start_mem); - start_mem += PAGE_SIZE; - } +#if CONFIG_X86_PAE + /* + * We will bail out later - printk doesnt work right now so + * the user would just see a hanging kernel. + */ + if (cpu_has_pae) + set_in_cr4(X86_CR4_PAE); +#endif + + __flush_tlb(); - pgd_val(*pg_dir) = _PAGE_TABLE | (unsigned long) pg_table; - pg_dir++; - - /* now change pg_table to kernel virtual addresses */ - pg_table = (pte_t *) __va(pg_table); - for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) { - pte_t pte = mk_pte(address, PAGE_KERNEL); - if (address >= end_mem) - pte_val(pte) = 0; - set_pte(pg_table, pte); - address += PAGE_SIZE; - } - } - start_mem = fixmap_init(start_mem); #ifdef __SMP__ - start_mem = init_smp_mappings(start_mem); + init_smp_mappings(); #endif - local_flush_tlb(); -#ifndef CONFIG_BIGMEM - return free_area_init(start_mem, end_mem); -#else +#ifdef CONFIG_HIGHMEM kmap_init(); /* run after fixmap_init */ - return free_area_init(start_mem, bigmem_end + PAGE_OFFSET); #endif +#ifdef CONFIG_HIGHMEM + free_area_init(highend_pfn); +#else + free_area_init(max_low_pfn); +#endif + return; } /* @@ -340,23 +432,38 @@ unsigned long __init paging_init(unsigned long start_mem, unsigned long end_mem) void __init test_wp_bit(void) { - unsigned char tmp_reg; - unsigned long old = pg0[0]; +/* + * Ok, all PAE-capable CPUs are definitely handling the WP bit right. + */ +//#ifndef CONFIG_X86_PAE + const unsigned long vaddr = PAGE_OFFSET; + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte, old_pte; + char tmp_reg; printk("Checking if this processor honours the WP bit even in supervisor mode... "); - pg0[0] = pte_val(mk_pte(PAGE_OFFSET, PAGE_READONLY)); + + pgd = swapper_pg_dir + __pgd_offset(vaddr); + pmd = pmd_offset(pgd, vaddr); + pte = pte_offset(pmd, vaddr); + old_pte = *pte; + *pte = mk_pte_phys(0, PAGE_READONLY); local_flush_tlb(); + __asm__ __volatile__( "jmp 1f; 1:\n" "movb %0,%1\n" "movb %1,%0\n" "jmp 1f; 1:\n" - :"=m" (*(char *) __va(0)), + :"=m" (*(char *) vaddr), "=q" (tmp_reg) :/* no inputs */ :"memory"); - pg0[0] = old; + + *pte = old_pte; local_flush_tlb(); + if (boot_cpu_data.wp_works_ok < 0) { boot_cpu_data.wp_works_ok = 0; printk("No.\n"); @@ -365,136 +472,95 @@ void __init test_wp_bit(void) #endif } else printk(".\n"); +//#endif } -static void __init mem_init_region(unsigned long pfn, unsigned long count, unsigned long start_mem_pfn) +static inline int page_is_ram (unsigned long pagenr) { - printk("memory region: %luk @ %08lx000\n", count << 2, pfn); + int i; - do { - if (pfn >= max_mapnr) - break; + for (i = 0; i < e820.nr_map; i++) { + unsigned long addr, size; - /* Avoid the kernel mapping between HIGH_MEMORY and "start_mem".. */ - if (pfn < (HIGH_MEMORY >> PAGE_SHIFT) || pfn >= start_mem_pfn) - clear_bit(PG_reserved, &mem_map[pfn].flags); - - pfn++; - } while (--count > 0); + if (e820.map[i].type != E820_RAM) /* not usable memory */ + continue; + addr = (e820.map[i].addr+PAGE_SIZE-1) >> PAGE_SHIFT; + size = e820.map[i].size >> PAGE_SHIFT; + if ((pagenr >= addr) && (pagenr < addr+size)) + return 1; + } + return 0; } -void __init mem_init(unsigned long start_mem, unsigned long end_mem) +void __init mem_init(void) { - unsigned long start_low_mem = PAGE_SIZE; int codepages = 0; int reservedpages = 0; int datapages = 0; int initpages = 0; - unsigned long tmp; - int i, avail; - - end_mem &= PAGE_MASK; -#ifdef CONFIG_BIGMEM - bigmem_start = PAGE_ALIGN(bigmem_start); - bigmem_end &= PAGE_MASK; -#endif - high_memory = (void *) end_mem; -#ifndef CONFIG_BIGMEM - max_mapnr = num_physpages = MAP_NR(end_mem); +#ifdef CONFIG_HIGHMEM + int tmp; + + if (!mem_map) + BUG(); + highmem_start_page = mem_map + highstart_pfn; + /* cache the highmem_mapnr */ + highmem_mapnr = highstart_pfn; + max_mapnr = num_physpages = highend_pfn; #else - max_mapnr = num_physpages = PHYSMAP_NR(bigmem_end); - /* cache the bigmem_mapnr */ - bigmem_mapnr = PHYSMAP_NR(bigmem_start); + max_mapnr = num_physpages = max_low_pfn; #endif + high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); /* clear the zero-page */ memset(empty_zero_page, 0, PAGE_SIZE); - /* mark usable pages in the mem_map[] */ - start_low_mem = PAGE_ALIGN(start_low_mem)+PAGE_OFFSET; + /* this will put all low memory onto the freelists */ + totalram_pages += free_all_bootmem(); -#ifdef __SMP__ - /* - * But first pinch a few for the stack/trampoline stuff - * FIXME: Don't need the extra page at 4K, but need to fix - * trampoline before removing it. (see the GDT stuff) - * - */ - start_low_mem += PAGE_SIZE; /* 32bit startup code */ - start_low_mem = smp_alloc_memory(start_low_mem); /* AP processor stacks */ -#endif - start_mem = PAGE_ALIGN(start_mem); +#ifdef CONFIG_HIGHMEM + for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) { + struct page *page = mem_map + tmp; - /* walk the whitelist, unreserving good memory - */ - for (avail = i = 0; i < e820.nr_map; i++) { - unsigned long start_pfn, end_pfn; - - if (e820.map[i].type != E820_RAM) /* not usable memory */ - continue; - - start_pfn = (e820.map[i].addr + PAGE_SIZE - 1) >> PAGE_SHIFT; - end_pfn = (e820.map[i].addr + e820.map[i].size) >> PAGE_SHIFT; - - /* We have a certain amount of low memory reserved */ - if (start_pfn < MAP_NR(start_low_mem)) - start_pfn = MAP_NR(start_low_mem); - - if (end_pfn <= start_pfn) - continue; - - mem_init_region(start_pfn, end_pfn - start_pfn, MAP_NR(start_mem)); - } - - for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) { - if (tmp >= MAX_DMA_ADDRESS) - clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags); - if (PageReserved(mem_map+MAP_NR(tmp))) { - 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++; + if (!page_is_ram(tmp)) { + SetPageReserved(page); continue; } - set_page_count(mem_map+MAP_NR(tmp), 1); - totalram += PAGE_SIZE; -#ifdef CONFIG_BLK_DEV_INITRD - if (!initrd_start || (tmp < initrd_start || tmp >= initrd_end)) -#endif - free_page(tmp); + ClearPageReserved(page); + set_bit(PG_highmem, &page->flags); + atomic_set(&page->count, 1); + __free_page(page); + totalhigh_pages++; } -#ifdef CONFIG_BIGMEM - for (tmp = bigmem_start; tmp < bigmem_end; tmp += PAGE_SIZE) { - clear_bit(PG_reserved, &mem_map[PHYSMAP_NR(tmp)].flags); - set_bit(PG_BIGMEM, &mem_map[PHYSMAP_NR(tmp)].flags); - atomic_set(&mem_map[PHYSMAP_NR(tmp)].count, 1); - free_page(tmp + PAGE_OFFSET); - totalbig += PAGE_SIZE; - } - totalram += totalbig; + totalram_pages += totalhigh_pages; #endif - printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %dk bigmem)\n", + printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\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), initpages << (PAGE_SHIFT-10), - (int) (totalbig >> 10) + (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)) ); +#if CONFIG_X86_PAE + if (!cpu_has_pae) + panic("cannot execute a PAE-enabled kernel on a PAE-incapable CPU!"); +#endif if (boot_cpu_data.wp_works_ok < 0) test_wp_bit(); + /* + * Subtle. SMP is doing it's boot stuff late (because it has to + * fork idle threads) - but it also needs low mappings for the + * protected-mode entry to work. We zap these entries only after + * the WP-bit has been tested. + */ +#ifndef CONFIG_SMP + zap_low_mappings(); +#endif + } void free_initmem(void) @@ -503,21 +569,22 @@ void free_initmem(void) addr = (unsigned long)(&__init_begin); for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { - mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved); + ClearPageReserved(mem_map + MAP_NR(addr)); set_page_count(mem_map+MAP_NR(addr), 1); free_page(addr); - totalram += PAGE_SIZE; + totalram_pages++; } printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10); } void si_meminfo(struct sysinfo *val) { - val->totalram = totalram; + val->totalram = totalram_pages; val->sharedram = 0; - val->freeram = nr_free_pages << PAGE_SHIFT; - val->bufferram = atomic_read(&buffermem); - val->totalbig = totalbig; - val->freebig = nr_free_bigpages << PAGE_SHIFT; + val->freeram = nr_free_pages; + val->bufferram = atomic_read(&buffermem_pages); + val->totalhigh = totalhigh_pages; + val->freehigh = nr_free_highpages; + val->mem_unit = PAGE_SIZE; return; } diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c index 32f3c33fd..d69455310 100644 --- a/arch/i386/mm/ioremap.c +++ b/arch/i386/mm/ioremap.c @@ -20,15 +20,19 @@ static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned l end = address + size; if (end > PMD_SIZE) end = PMD_SIZE; + if (address >= end) + BUG(); do { - if (!pte_none(*pte)) + if (!pte_none(*pte)) { printk("remap_area_pte: page already exists\n"); + BUG(); + } set_pte(pte, mk_pte_phys(phys_addr, __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED | flags))); address += PAGE_SIZE; phys_addr += PAGE_SIZE; pte++; - } while (address < end); + } while (address && (address < end)); } static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size, @@ -41,6 +45,8 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo if (end > PGDIR_SIZE) end = PGDIR_SIZE; phys_addr -= address; + if (address >= end) + BUG(); do { pte_t * pte = pte_alloc_kernel(pmd, address); if (!pte) @@ -48,7 +54,7 @@ static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned lo remap_area_pte(pte, address, end - address, address + phys_addr, flags); address = (address + PMD_SIZE) & PMD_MASK; pmd++; - } while (address < end); + } while (address && (address < end)); return 0; } @@ -61,8 +67,11 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr, phys_addr -= address; dir = pgd_offset(&init_mm, address); flush_cache_all(); - while (address < end) { - pmd_t *pmd = pmd_alloc_kernel(dir, address); + if (address >= end) + BUG(); + do { + pmd_t *pmd; + pmd = pmd_alloc_kernel(dir, address); if (!pmd) return -ENOMEM; if (remap_area_pmd(pmd, address, end - address, @@ -71,7 +80,7 @@ static int remap_area_pages(unsigned long address, unsigned long phys_addr, set_pgdir(address, *dir); address = (address + PGDIR_SIZE) & PGDIR_MASK; dir++; - } + } while (address && (address < end)); flush_tlb_all(); return 0; } diff --git a/arch/i386/vmlinux.lds b/arch/i386/vmlinux.lds new file mode 100644 index 000000000..9624cae47 --- /dev/null +++ b/arch/i386/vmlinux.lds @@ -0,0 +1,75 @@ +/* ld script to make i386 Linux kernel + * Written by Martin Mares ; + */ +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) +SECTIONS +{ + . = 0xC0000000 + 0x100000; + _text = .; /* Text and read-only data */ + .text : { + *(.text) + *(.fixup) + *(.gnu.warning) + } = 0x9090 + .text.lock : { *(.text.lock) } /* out-of-line lock text */ + .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(8192); /* init_task */ + .data.init_task : { *(.data.init_task) } + + . = ALIGN(4096); /* Init code and data */ + __init_begin = .; + .text.init : { *(.text.init) } + .data.init : { *(.data.init) } + . = ALIGN(16); + __setup_start = .; + .setup.init : { *(.setup.init) } + __setup_end = .; + __initcall_start = .; + .initcall.init : { *(.initcall.init) } + __initcall_end = .; + . = ALIGN(4096); + __init_end = .; + + . = ALIGN(4096); + .data.page_aligned : { *(.data.idt) } + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + __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) } +} diff --git a/arch/i386/vmlinux.lds.S b/arch/i386/vmlinux.lds.S deleted file mode 100644 index 9a9ff07e7..000000000 --- a/arch/i386/vmlinux.lds.S +++ /dev/null @@ -1,75 +0,0 @@ -/* ld script to make i386 Linux kernel - * Written by Martin Mares ; - */ -OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") -OUTPUT_ARCH(i386) -ENTRY(_start) -SECTIONS -{ - . = PAGE_OFFSET_RAW + 0x100000; - _text = .; /* Text and read-only data */ - .text : { - *(.text) - *(.fixup) - *(.gnu.warning) - } = 0x9090 - .text.lock : { *(.text.lock) } /* out-of-line lock text */ - .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(8192); /* init_task */ - .data.init_task : { *(.data.init_task) } - - . = ALIGN(4096); /* Init code and data */ - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(16); - __setup_start = .; - .setup.init : { *(.setup.init) } - __setup_end = .; - __initcall_start = .; - .initcall.init : { *(.initcall.init) } - __initcall_end = .; - . = ALIGN(4096); - __init_end = .; - - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - - . = ALIGN(32); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - __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) } -} -- cgit v1.2.3