diff options
author | H. Peter Anvin <hpa@zytor.com> | 2007-07-11 15:18:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-12 13:55:55 -0400 |
commit | 91a6c462b02d8dc02dbe95e5a407d78078a38d01 (patch) | |
tree | 46ad95267332ca895b3af2d40def2e89e18aafd8 | |
parent | 4fd06960f120e02e9abc802a09f9511c400042a5 (diff) |
Use the new x86 setup code for x86-64; unify with i386
This unifies arch/*/boot (except arch/*/boot/compressed) between
i386 and x86-64, and uses the new x86 setup code for x86-64 as well.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | arch/x86_64/boot/Makefile | 136 | ||||
-rw-r--r-- | arch/x86_64/boot/bootsect.S | 98 | ||||
-rw-r--r-- | arch/x86_64/boot/compressed/Makefile | 9 | ||||
-rw-r--r-- | arch/x86_64/boot/install.sh | 2 | ||||
-rw-r--r-- | arch/x86_64/boot/mtools.conf.in | 17 | ||||
-rw-r--r-- | arch/x86_64/boot/setup.S | 826 | ||||
-rw-r--r-- | arch/x86_64/boot/tools/build.c | 185 |
7 files changed, 10 insertions, 1263 deletions
diff --git a/arch/x86_64/boot/Makefile b/arch/x86_64/boot/Makefile index ee6f6505f95f..67096389de1f 100644 --- a/arch/x86_64/boot/Makefile +++ b/arch/x86_64/boot/Makefile | |||
@@ -1,135 +1,9 @@ | |||
1 | # | 1 | # |
2 | # arch/x86_64/boot/Makefile | 2 | # arch/x86_64/boot/Makefile |
3 | # | 3 | # |
4 | # This file is subject to the terms and conditions of the GNU General Public | 4 | # The actual boot code is shared with i386 including the Makefile. |
5 | # License. See the file "COPYING" in the main directory of this archive | 5 | # So tell kbuild that we fetch the code from i386 and include the |
6 | # for more details. | 6 | # Makefile from i386 too. |
7 | # | ||
8 | # Copyright (C) 1994 by Linus Torvalds | ||
9 | # | ||
10 | |||
11 | # ROOT_DEV specifies the default root-device when making the image. | ||
12 | # This can be either FLOPPY, CURRENT, /dev/xxxx or empty, in which case | ||
13 | # the default of FLOPPY is used by 'build'. | ||
14 | |||
15 | ROOT_DEV := CURRENT | ||
16 | |||
17 | # If you want to preset the SVGA mode, uncomment the next line and | ||
18 | # set SVGA_MODE to whatever number you want. | ||
19 | # Set it to -DSVGA_MODE=NORMAL_VGA if you just want the EGA/VGA mode. | ||
20 | # The number is the same as you would ordinarily press at bootup. | ||
21 | |||
22 | SVGA_MODE := -DSVGA_MODE=NORMAL_VGA | ||
23 | |||
24 | # If you want the RAM disk device, define this to be the size in blocks. | ||
25 | |||
26 | #RAMDISK := -DRAMDISK=512 | ||
27 | |||
28 | targets := vmlinux.bin bootsect bootsect.o \ | ||
29 | setup setup.o bzImage mtools.conf | ||
30 | |||
31 | EXTRA_CFLAGS := -m32 | ||
32 | |||
33 | hostprogs-y := tools/build | ||
34 | HOST_EXTRACFLAGS += $(LINUXINCLUDE) | ||
35 | subdir- := compressed/ #Let make clean descend in compressed/ | ||
36 | # --------------------------------------------------------------------------- | ||
37 | |||
38 | $(obj)/bzImage: IMAGE_OFFSET := 0x100000 | ||
39 | $(obj)/bzImage: EXTRA_AFLAGS := $(SVGA_MODE) $(RAMDISK) -D__BIG_KERNEL__ | ||
40 | $(obj)/bzImage: BUILDFLAGS := -b | ||
41 | |||
42 | quiet_cmd_image = BUILD $@ | ||
43 | cmd_image = $(obj)/tools/build $(BUILDFLAGS) $(obj)/bootsect $(obj)/setup \ | ||
44 | $(obj)/vmlinux.bin $(ROOT_DEV) > $@ | ||
45 | |||
46 | $(obj)/bzImage: $(obj)/bootsect $(obj)/setup \ | ||
47 | $(obj)/vmlinux.bin $(obj)/tools/build FORCE | ||
48 | $(call if_changed,image) | ||
49 | @echo 'Kernel: $@ is ready' ' (#'`cat .version`')' | ||
50 | |||
51 | $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE | ||
52 | $(call if_changed,objcopy) | ||
53 | |||
54 | LDFLAGS_bootsect := -Ttext 0x0 -s --oformat binary | ||
55 | LDFLAGS_setup := -Ttext 0x0 -s --oformat binary -e begtext | ||
56 | |||
57 | $(obj)/setup $(obj)/bootsect: %: %.o FORCE | ||
58 | $(call if_changed,ld) | ||
59 | |||
60 | $(obj)/compressed/vmlinux: FORCE | ||
61 | $(Q)$(MAKE) $(build)=$(obj)/compressed IMAGE_OFFSET=$(IMAGE_OFFSET) $@ | ||
62 | |||
63 | # Set this if you want to pass append arguments to the zdisk/fdimage/isoimage kernel | ||
64 | FDARGS = | ||
65 | # Set this if you want an initrd included with the zdisk/fdimage/isoimage kernel | ||
66 | FDINITRD = | ||
67 | |||
68 | image_cmdline = default linux $(FDARGS) $(if $(FDINITRD),initrd=initrd.img,) | ||
69 | |||
70 | $(obj)/mtools.conf: $(src)/mtools.conf.in | ||
71 | sed -e 's|@OBJ@|$(obj)|g' < $< > $@ | ||
72 | |||
73 | # This requires write access to /dev/fd0 | ||
74 | zdisk: $(BOOTIMAGE) $(obj)/mtools.conf | ||
75 | MTOOLSRC=$(obj)/mtools.conf mformat a: ; sync | ||
76 | syslinux /dev/fd0 ; sync | ||
77 | echo '$(image_cmdline)' | \ | ||
78 | MTOOLSRC=$(obj)/mtools.conf mcopy - a:syslinux.cfg | ||
79 | if [ -f '$(FDINITRD)' ] ; then \ | ||
80 | MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' a:initrd.img ; \ | ||
81 | fi | ||
82 | MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) a:linux ; sync | ||
83 | |||
84 | # These require being root or having syslinux 2.02 or higher installed | ||
85 | fdimage fdimage144: $(BOOTIMAGE) $(obj)/mtools.conf | ||
86 | dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=1440 | ||
87 | MTOOLSRC=$(obj)/mtools.conf mformat v: ; sync | ||
88 | syslinux $(obj)/fdimage ; sync | ||
89 | echo '$(image_cmdline)' | \ | ||
90 | MTOOLSRC=$(obj)/mtools.conf mcopy - v:syslinux.cfg | ||
91 | if [ -f '$(FDINITRD)' ] ; then \ | ||
92 | MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' v:initrd.img ; \ | ||
93 | fi | ||
94 | MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) v:linux ; sync | ||
95 | |||
96 | fdimage288: $(BOOTIMAGE) $(obj)/mtools.conf | ||
97 | dd if=/dev/zero of=$(obj)/fdimage bs=1024 count=2880 | ||
98 | MTOOLSRC=$(obj)/mtools.conf mformat w: ; sync | ||
99 | syslinux $(obj)/fdimage ; sync | ||
100 | echo '$(image_cmdline)' | \ | ||
101 | MTOOLSRC=$(obj)/mtools.conf mcopy - w:syslinux.cfg | ||
102 | if [ -f '$(FDINITRD)' ] ; then \ | ||
103 | MTOOLSRC=$(obj)/mtools.conf mcopy '$(FDINITRD)' w:initrd.img ; \ | ||
104 | fi | ||
105 | MTOOLSRC=$(obj)/mtools.conf mcopy $(BOOTIMAGE) w:linux ; sync | ||
106 | |||
107 | isoimage: $(BOOTIMAGE) | ||
108 | -rm -rf $(obj)/isoimage | ||
109 | mkdir $(obj)/isoimage | ||
110 | for i in lib lib64 share end ; do \ | ||
111 | if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \ | ||
112 | cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \ | ||
113 | break ; \ | ||
114 | fi ; \ | ||
115 | if [ $$i = end ] ; then exit 1 ; fi ; \ | ||
116 | done | ||
117 | cp $(BOOTIMAGE) $(obj)/isoimage/linux | ||
118 | echo '$(image_cmdline)' > $(obj)/isoimage/isolinux.cfg | ||
119 | if [ -f '$(FDINITRD)' ] ; then \ | ||
120 | cp '$(FDINITRD)' $(obj)/isoimage/initrd.img ; \ | ||
121 | fi | ||
122 | mkisofs -J -r -o $(obj)/image.iso -b isolinux.bin -c boot.cat \ | ||
123 | -no-emul-boot -boot-load-size 4 -boot-info-table \ | ||
124 | $(obj)/isoimage | ||
125 | rm -rf $(obj)/isoimage | ||
126 | |||
127 | zlilo: $(BOOTIMAGE) | ||
128 | if [ -f $(INSTALL_PATH)/vmlinuz ]; then mv $(INSTALL_PATH)/vmlinuz $(INSTALL_PATH)/vmlinuz.old; fi | ||
129 | if [ -f $(INSTALL_PATH)/System.map ]; then mv $(INSTALL_PATH)/System.map $(INSTALL_PATH)/System.old; fi | ||
130 | cat $(BOOTIMAGE) > $(INSTALL_PATH)/vmlinuz | ||
131 | cp System.map $(INSTALL_PATH)/ | ||
132 | if [ -x /sbin/lilo ]; then /sbin/lilo; else /etc/lilo/install; fi | ||
133 | 7 | ||
134 | install: | 8 | src := arch/i386/boot |
135 | sh $(srctree)/$(src)/install.sh $(KERNELRELEASE) $(BOOTIMAGE) System.map "$(INSTALL_PATH)" | 9 | include $(src)/Makefile |
diff --git a/arch/x86_64/boot/bootsect.S b/arch/x86_64/boot/bootsect.S deleted file mode 100644 index 011b7a4993d4..000000000000 --- a/arch/x86_64/boot/bootsect.S +++ /dev/null | |||
@@ -1,98 +0,0 @@ | |||
1 | /* | ||
2 | * bootsect.S Copyright (C) 1991, 1992 Linus Torvalds | ||
3 | * | ||
4 | * modified by Drew Eckhardt | ||
5 | * modified by Bruce Evans (bde) | ||
6 | * modified by Chris Noe (May 1999) (as86 -> gas) | ||
7 | * gutted by H. Peter Anvin (Jan 2003) | ||
8 | * | ||
9 | * BIG FAT NOTE: We're in real mode using 64k segments. Therefore segment | ||
10 | * addresses must be multiplied by 16 to obtain their respective linear | ||
11 | * addresses. To avoid confusion, linear addresses are written using leading | ||
12 | * hex while segment addresses are written as segment:offset. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <asm/boot.h> | ||
17 | |||
18 | SETUPSECTS = 4 /* default nr of setup-sectors */ | ||
19 | BOOTSEG = 0x07C0 /* original address of boot-sector */ | ||
20 | INITSEG = DEF_INITSEG /* we move boot here - out of the way */ | ||
21 | SETUPSEG = DEF_SETUPSEG /* setup starts here */ | ||
22 | SYSSEG = DEF_SYSSEG /* system loaded at 0x10000 (65536) */ | ||
23 | SYSSIZE = DEF_SYSSIZE /* system size: # of 16-byte clicks */ | ||
24 | /* to be loaded */ | ||
25 | ROOT_DEV = 0 /* ROOT_DEV is now written by "build" */ | ||
26 | SWAP_DEV = 0 /* SWAP_DEV is now written by "build" */ | ||
27 | |||
28 | #ifndef SVGA_MODE | ||
29 | #define SVGA_MODE ASK_VGA | ||
30 | #endif | ||
31 | |||
32 | #ifndef RAMDISK | ||
33 | #define RAMDISK 0 | ||
34 | #endif | ||
35 | |||
36 | #ifndef ROOT_RDONLY | ||
37 | #define ROOT_RDONLY 1 | ||
38 | #endif | ||
39 | |||
40 | .code16 | ||
41 | .text | ||
42 | |||
43 | .global _start | ||
44 | _start: | ||
45 | |||
46 | # Normalize the start address | ||
47 | jmpl $BOOTSEG, $start2 | ||
48 | |||
49 | start2: | ||
50 | movw %cs, %ax | ||
51 | movw %ax, %ds | ||
52 | movw %ax, %es | ||
53 | movw %ax, %ss | ||
54 | movw $0x7c00, %sp | ||
55 | sti | ||
56 | cld | ||
57 | |||
58 | movw $bugger_off_msg, %si | ||
59 | |||
60 | msg_loop: | ||
61 | lodsb | ||
62 | andb %al, %al | ||
63 | jz die | ||
64 | movb $0xe, %ah | ||
65 | movw $7, %bx | ||
66 | int $0x10 | ||
67 | jmp msg_loop | ||
68 | |||
69 | die: | ||
70 | # Allow the user to press a key, then reboot | ||
71 | xorw %ax, %ax | ||
72 | int $0x16 | ||
73 | int $0x19 | ||
74 | |||
75 | # int 0x19 should never return. In case it does anyway, | ||
76 | # invoke the BIOS reset code... | ||
77 | ljmp $0xf000,$0xfff0 | ||
78 | |||
79 | |||
80 | bugger_off_msg: | ||
81 | .ascii "Direct booting from floppy is no longer supported.\r\n" | ||
82 | .ascii "Please use a boot loader program instead.\r\n" | ||
83 | .ascii "\n" | ||
84 | .ascii "Remove disk and press any key to reboot . . .\r\n" | ||
85 | .byte 0 | ||
86 | |||
87 | |||
88 | # Kernel attributes; used by setup | ||
89 | |||
90 | .org 497 | ||
91 | setup_sects: .byte SETUPSECTS | ||
92 | root_flags: .word ROOT_RDONLY | ||
93 | syssize: .word SYSSIZE | ||
94 | swap_dev: .word SWAP_DEV | ||
95 | ram_size: .word RAMDISK | ||
96 | vid_mode: .word SVGA_MODE | ||
97 | root_dev: .word ROOT_DEV | ||
98 | boot_flag: .word 0xAA55 | ||
diff --git a/arch/x86_64/boot/compressed/Makefile b/arch/x86_64/boot/compressed/Makefile index 705a3e33d7e1..c9f2da7496c1 100644 --- a/arch/x86_64/boot/compressed/Makefile +++ b/arch/x86_64/boot/compressed/Makefile | |||
@@ -7,11 +7,12 @@ | |||
7 | # | 7 | # |
8 | 8 | ||
9 | targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o | 9 | targets := vmlinux vmlinux.bin vmlinux.bin.gz head.o misc.o piggy.o |
10 | EXTRA_AFLAGS := -traditional | ||
11 | 10 | ||
12 | # cannot use EXTRA_CFLAGS because base CFLAGS contains -mkernel which conflicts with | 11 | CFLAGS := -m64 -D__KERNEL__ $(LINUXINCLUDE) -O2 \ |
13 | # -m32 | 12 | -fno-strict-aliasing -fPIC -mcmodel=small \ |
14 | CFLAGS := -m64 -D__KERNEL__ -Iinclude -O2 -fno-strict-aliasing -fPIC -mcmodel=small -fno-builtin | 13 | $(call cc-option, -ffreestanding) \ |
14 | $(call cc-option, -fno-stack-protector) | ||
15 | AFLAGS := $(CFLAGS) -D__ASSEMBLY__ | ||
15 | LDFLAGS := -m elf_x86_64 | 16 | LDFLAGS := -m elf_x86_64 |
16 | 17 | ||
17 | LDFLAGS_vmlinux := -T | 18 | LDFLAGS_vmlinux := -T |
diff --git a/arch/x86_64/boot/install.sh b/arch/x86_64/boot/install.sh deleted file mode 100644 index baaa2369bdb8..000000000000 --- a/arch/x86_64/boot/install.sh +++ /dev/null | |||
@@ -1,2 +0,0 @@ | |||
1 | #!/bin/sh | ||
2 | . $srctree/arch/i386/boot/install.sh | ||
diff --git a/arch/x86_64/boot/mtools.conf.in b/arch/x86_64/boot/mtools.conf.in deleted file mode 100644 index efd6d2490c1d..000000000000 --- a/arch/x86_64/boot/mtools.conf.in +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | # | ||
2 | # mtools configuration file for "make (b)zdisk" | ||
3 | # | ||
4 | |||
5 | # Actual floppy drive | ||
6 | drive a: | ||
7 | file="/dev/fd0" | ||
8 | |||
9 | # 1.44 MB floppy disk image | ||
10 | drive v: | ||
11 | file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=18 filter | ||
12 | |||
13 | # 2.88 MB floppy disk image (mostly for virtual uses) | ||
14 | drive w: | ||
15 | file="@OBJ@/fdimage" cylinders=80 heads=2 sectors=36 filter | ||
16 | |||
17 | |||
diff --git a/arch/x86_64/boot/setup.S b/arch/x86_64/boot/setup.S deleted file mode 100644 index e9e33f949697..000000000000 --- a/arch/x86_64/boot/setup.S +++ /dev/null | |||
@@ -1,826 +0,0 @@ | |||
1 | /* | ||
2 | * setup.S Copyright (C) 1991, 1992 Linus Torvalds | ||
3 | * | ||
4 | * setup.s is responsible for getting the system data from the BIOS, | ||
5 | * and putting them into the appropriate places in system memory. | ||
6 | * both setup.s and system has been loaded by the bootblock. | ||
7 | * | ||
8 | * This code asks the bios for memory/disk/other parameters, and | ||
9 | * puts them in a "safe" place: 0x90000-0x901FF, ie where the | ||
10 | * boot-block used to be. It is then up to the protected mode | ||
11 | * system to read them from there before the area is overwritten | ||
12 | * for buffer-blocks. | ||
13 | * | ||
14 | * Move PS/2 aux init code to psaux.c | ||
15 | * (troyer@saifr00.cfsat.Honeywell.COM) 03Oct92 | ||
16 | * | ||
17 | * some changes and additional features by Christoph Niemann, | ||
18 | * March 1993/June 1994 (Christoph.Niemann@linux.org) | ||
19 | * | ||
20 | * add APM BIOS checking by Stephen Rothwell, May 1994 | ||
21 | * (sfr@canb.auug.org.au) | ||
22 | * | ||
23 | * High load stuff, initrd support and position independency | ||
24 | * by Hans Lermen & Werner Almesberger, February 1996 | ||
25 | * <lermen@elserv.ffm.fgan.de>, <almesber@lrc.epfl.ch> | ||
26 | * | ||
27 | * Video handling moved to video.S by Martin Mares, March 1996 | ||
28 | * <mj@k332.feld.cvut.cz> | ||
29 | * | ||
30 | * Extended memory detection scheme retwiddled by orc@pell.chi.il.us (david | ||
31 | * parsons) to avoid loadlin confusion, July 1997 | ||
32 | * | ||
33 | * Transcribed from Intel (as86) -> AT&T (gas) by Chris Noe, May 1999. | ||
34 | * <stiker@northlink.com> | ||
35 | * | ||
36 | * Fix to work around buggy BIOSes which don't use carry bit correctly | ||
37 | * and/or report extended memory in CX/DX for e801h memory size detection | ||
38 | * call. As a result the kernel got wrong figures. The int15/e801h docs | ||
39 | * from Ralf Brown interrupt list seem to indicate AX/BX should be used | ||
40 | * anyway. So to avoid breaking many machines (presumably there was a reason | ||
41 | * to orginally use CX/DX instead of AX/BX), we do a kludge to see | ||
42 | * if CX/DX have been changed in the e801 call and if so use AX/BX . | ||
43 | * Michael Miller, April 2001 <michaelm@mjmm.org> | ||
44 | * | ||
45 | * Added long mode checking and SSE force. March 2003, Andi Kleen. | ||
46 | */ | ||
47 | |||
48 | #include <asm/segment.h> | ||
49 | #include <linux/utsrelease.h> | ||
50 | #include <linux/compile.h> | ||
51 | #include <asm/boot.h> | ||
52 | #include <asm/e820.h> | ||
53 | #include <asm/page.h> | ||
54 | #include <asm/setup.h> | ||
55 | |||
56 | /* Signature words to ensure LILO loaded us right */ | ||
57 | #define SIG1 0xAA55 | ||
58 | #define SIG2 0x5A5A | ||
59 | |||
60 | INITSEG = DEF_INITSEG # 0x9000, we move boot here, out of the way | ||
61 | SYSSEG = DEF_SYSSEG # 0x1000, system loaded at 0x10000 (65536). | ||
62 | SETUPSEG = DEF_SETUPSEG # 0x9020, this is the current segment | ||
63 | # ... and the former contents of CS | ||
64 | |||
65 | DELTA_INITSEG = SETUPSEG - INITSEG # 0x0020 | ||
66 | |||
67 | .code16 | ||
68 | .globl begtext, begdata, begbss, endtext, enddata, endbss | ||
69 | |||
70 | .text | ||
71 | begtext: | ||
72 | .data | ||
73 | begdata: | ||
74 | .bss | ||
75 | begbss: | ||
76 | .text | ||
77 | |||
78 | start: | ||
79 | jmp trampoline | ||
80 | |||
81 | # This is the setup header, and it must start at %cs:2 (old 0x9020:2) | ||
82 | |||
83 | .ascii "HdrS" # header signature | ||
84 | .word 0x0206 # header version number (>= 0x0105) | ||
85 | # or else old loadlin-1.5 will fail) | ||
86 | realmode_swtch: .word 0, 0 # default_switch, SETUPSEG | ||
87 | start_sys_seg: .word SYSSEG | ||
88 | .word kernel_version # pointing to kernel version string | ||
89 | # above section of header is compatible | ||
90 | # with loadlin-1.5 (header v1.5). Don't | ||
91 | # change it. | ||
92 | |||
93 | type_of_loader: .byte 0 # = 0, old one (LILO, Loadlin, | ||
94 | # Bootlin, SYSLX, bootsect...) | ||
95 | # See Documentation/i386/boot.txt for | ||
96 | # assigned ids | ||
97 | |||
98 | # flags, unused bits must be zero (RFU) bit within loadflags | ||
99 | loadflags: | ||
100 | LOADED_HIGH = 1 # If set, the kernel is loaded high | ||
101 | CAN_USE_HEAP = 0x80 # If set, the loader also has set | ||
102 | # heap_end_ptr to tell how much | ||
103 | # space behind setup.S can be used for | ||
104 | # heap purposes. | ||
105 | # Only the loader knows what is free | ||
106 | #ifndef __BIG_KERNEL__ | ||
107 | .byte 0 | ||
108 | #else | ||
109 | .byte LOADED_HIGH | ||
110 | #endif | ||
111 | |||
112 | setup_move_size: .word 0x8000 # size to move, when setup is not | ||
113 | # loaded at 0x90000. We will move setup | ||
114 | # to 0x90000 then just before jumping | ||
115 | # into the kernel. However, only the | ||
116 | # loader knows how much data behind | ||
117 | # us also needs to be loaded. | ||
118 | |||
119 | code32_start: # here loaders can put a different | ||
120 | # start address for 32-bit code. | ||
121 | #ifndef __BIG_KERNEL__ | ||
122 | .long 0x1000 # 0x1000 = default for zImage | ||
123 | #else | ||
124 | .long 0x100000 # 0x100000 = default for big kernel | ||
125 | #endif | ||
126 | |||
127 | ramdisk_image: .long 0 # address of loaded ramdisk image | ||
128 | # Here the loader puts the 32-bit | ||
129 | # address where it loaded the image. | ||
130 | # This only will be read by the kernel. | ||
131 | |||
132 | ramdisk_size: .long 0 # its size in bytes | ||
133 | |||
134 | bootsect_kludge: | ||
135 | .long 0 # obsolete | ||
136 | |||
137 | heap_end_ptr: .word modelist+1024 # (Header version 0x0201 or later) | ||
138 | # space from here (exclusive) down to | ||
139 | # end of setup code can be used by setup | ||
140 | # for local heap purposes. | ||
141 | |||
142 | pad1: .word 0 | ||
143 | cmd_line_ptr: .long 0 # (Header version 0x0202 or later) | ||
144 | # If nonzero, a 32-bit pointer | ||
145 | # to the kernel command line. | ||
146 | # The command line should be | ||
147 | # located between the start of | ||
148 | # setup and the end of low | ||
149 | # memory (0xa0000), or it may | ||
150 | # get overwritten before it | ||
151 | # gets read. If this field is | ||
152 | # used, there is no longer | ||
153 | # anything magical about the | ||
154 | # 0x90000 segment; the setup | ||
155 | # can be located anywhere in | ||
156 | # low memory 0x10000 or higher. | ||
157 | |||
158 | ramdisk_max: .long 0xffffffff | ||
159 | kernel_alignment: .long 0x200000 # physical addr alignment required for | ||
160 | # protected mode relocatable kernel | ||
161 | #ifdef CONFIG_RELOCATABLE | ||
162 | relocatable_kernel: .byte 1 | ||
163 | #else | ||
164 | relocatable_kernel: .byte 0 | ||
165 | #endif | ||
166 | pad2: .byte 0 | ||
167 | pad3: .word 0 | ||
168 | |||
169 | cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line, | ||
170 | #added with boot protocol | ||
171 | #version 2.06 | ||
172 | |||
173 | trampoline: call start_of_setup | ||
174 | .align 16 | ||
175 | # The offset at this point is 0x240 | ||
176 | .space (0xeff-0x240+1) # E820 & EDD space (ending at 0xeff) | ||
177 | # End of setup header ##################################################### | ||
178 | |||
179 | start_of_setup: | ||
180 | # Bootlin depends on this being done early | ||
181 | movw $0x01500, %ax | ||
182 | movb $0x81, %dl | ||
183 | int $0x13 | ||
184 | |||
185 | #ifdef SAFE_RESET_DISK_CONTROLLER | ||
186 | # Reset the disk controller. | ||
187 | movw $0x0000, %ax | ||
188 | movb $0x80, %dl | ||
189 | int $0x13 | ||
190 | #endif | ||
191 | |||
192 | # Set %ds = %cs, we know that SETUPSEG = %cs at this point | ||
193 | movw %cs, %ax # aka SETUPSEG | ||
194 | movw %ax, %ds | ||
195 | # Check signature at end of setup | ||
196 | cmpw $SIG1, setup_sig1 | ||
197 | jne bad_sig | ||
198 | |||
199 | cmpw $SIG2, setup_sig2 | ||
200 | jne bad_sig | ||
201 | |||
202 | jmp good_sig1 | ||
203 | |||
204 | # Routine to print asciiz string at ds:si | ||
205 | prtstr: | ||
206 | lodsb | ||
207 | andb %al, %al | ||
208 | jz fin | ||
209 | |||
210 | call prtchr | ||
211 | jmp prtstr | ||
212 | |||
213 | fin: ret | ||
214 | |||
215 | # Space printing | ||
216 | prtsp2: call prtspc # Print double space | ||
217 | prtspc: movb $0x20, %al # Print single space (note: fall-thru) | ||
218 | |||
219 | prtchr: | ||
220 | pushw %ax | ||
221 | pushw %cx | ||
222 | movw $0007,%bx | ||
223 | movw $0x01, %cx | ||
224 | movb $0x0e, %ah | ||
225 | int $0x10 | ||
226 | popw %cx | ||
227 | popw %ax | ||
228 | ret | ||
229 | |||
230 | beep: movb $0x07, %al | ||
231 | jmp prtchr | ||
232 | |||
233 | no_sig_mess: .string "No setup signature found ..." | ||
234 | |||
235 | good_sig1: | ||
236 | jmp good_sig | ||
237 | |||
238 | # We now have to find the rest of the setup code/data | ||
239 | bad_sig: | ||
240 | movw %cs, %ax # SETUPSEG | ||
241 | subw $DELTA_INITSEG, %ax # INITSEG | ||
242 | movw %ax, %ds | ||
243 | xorb %bh, %bh | ||
244 | movb (497), %bl # get setup sect from bootsect | ||
245 | subw $4, %bx # LILO loads 4 sectors of setup | ||
246 | shlw $8, %bx # convert to words (1sect=2^8 words) | ||
247 | movw %bx, %cx | ||
248 | shrw $3, %bx # convert to segment | ||
249 | addw $SYSSEG, %bx | ||
250 | movw %bx, %cs:start_sys_seg | ||
251 | # Move rest of setup code/data to here | ||
252 | movw $2048, %di # four sectors loaded by LILO | ||
253 | subw %si, %si | ||
254 | movw %cs, %ax # aka SETUPSEG | ||
255 | movw %ax, %es | ||
256 | movw $SYSSEG, %ax | ||
257 | movw %ax, %ds | ||
258 | rep | ||
259 | movsw | ||
260 | movw %cs, %ax # aka SETUPSEG | ||
261 | movw %ax, %ds | ||
262 | cmpw $SIG1, setup_sig1 | ||
263 | jne no_sig | ||
264 | |||
265 | cmpw $SIG2, setup_sig2 | ||
266 | jne no_sig | ||
267 | |||
268 | jmp good_sig | ||
269 | |||
270 | no_sig: | ||
271 | lea no_sig_mess, %si | ||
272 | call prtstr | ||
273 | |||
274 | no_sig_loop: | ||
275 | jmp no_sig_loop | ||
276 | |||
277 | good_sig: | ||
278 | movw %cs, %ax # aka SETUPSEG | ||
279 | subw $DELTA_INITSEG, %ax # aka INITSEG | ||
280 | movw %ax, %ds | ||
281 | # Check if an old loader tries to load a big-kernel | ||
282 | testb $LOADED_HIGH, %cs:loadflags # Do we have a big kernel? | ||
283 | jz loader_ok # No, no danger for old loaders. | ||
284 | |||
285 | cmpb $0, %cs:type_of_loader # Do we have a loader that | ||
286 | # can deal with us? | ||
287 | jnz loader_ok # Yes, continue. | ||
288 | |||
289 | pushw %cs # No, we have an old loader, | ||
290 | popw %ds # die. | ||
291 | lea loader_panic_mess, %si | ||
292 | call prtstr | ||
293 | |||
294 | jmp no_sig_loop | ||
295 | |||
296 | loader_panic_mess: .string "Wrong loader, giving up..." | ||
297 | |||
298 | loader_ok: | ||
299 | /* check for long mode. */ | ||
300 | /* we have to do this before the VESA setup, otherwise the user | ||
301 | can't see the error message. */ | ||
302 | |||
303 | pushw %ds | ||
304 | movw %cs,%ax | ||
305 | movw %ax,%ds | ||
306 | |||
307 | call verify_cpu | ||
308 | testl %eax,%eax | ||
309 | jz sse_ok | ||
310 | |||
311 | no_longmode: | ||
312 | call beep | ||
313 | lea long_mode_panic,%si | ||
314 | call prtstr | ||
315 | no_longmode_loop: | ||
316 | jmp no_longmode_loop | ||
317 | long_mode_panic: | ||
318 | .string "Your CPU does not support long mode. Use a 32bit distribution." | ||
319 | .byte 0 | ||
320 | |||
321 | #include "../kernel/verify_cpu.S" | ||
322 | sse_ok: | ||
323 | popw %ds | ||
324 | |||
325 | # tell BIOS we want to go to long mode | ||
326 | movl $0xec00,%eax # declare target operating mode | ||
327 | movl $2,%ebx # long mode | ||
328 | int $0x15 | ||
329 | |||
330 | # Get memory size (extended mem, kB) | ||
331 | |||
332 | xorl %eax, %eax | ||
333 | movl %eax, (0x1e0) | ||
334 | #ifndef STANDARD_MEMORY_BIOS_CALL | ||
335 | movb %al, (E820NR) | ||
336 | # Try three different memory detection schemes. First, try | ||
337 | # e820h, which lets us assemble a memory map, then try e801h, | ||
338 | # which returns a 32-bit memory size, and finally 88h, which | ||
339 | # returns 0-64m | ||
340 | |||
341 | # method E820H: | ||
342 | # the memory map from hell. e820h returns memory classified into | ||
343 | # a whole bunch of different types, and allows memory holes and | ||
344 | # everything. We scan through this memory map and build a list | ||
345 | # of the first 32 memory areas, which we return at [E820MAP]. | ||
346 | # This is documented at http://www.acpi.info/, in the ACPI 2.0 specification. | ||
347 | |||
348 | #define SMAP 0x534d4150 | ||
349 | |||
350 | meme820: | ||
351 | xorl %ebx, %ebx # continuation counter | ||
352 | movw $E820MAP, %di # point into the whitelist | ||
353 | # so we can have the bios | ||
354 | # directly write into it. | ||
355 | |||
356 | jmpe820: | ||
357 | movl $0x0000e820, %eax # e820, upper word zeroed | ||
358 | movl $SMAP, %edx # ascii 'SMAP' | ||
359 | movl $20, %ecx # size of the e820rec | ||
360 | pushw %ds # data record. | ||
361 | popw %es | ||
362 | int $0x15 # make the call | ||
363 | jc bail820 # fall to e801 if it fails | ||
364 | |||
365 | cmpl $SMAP, %eax # check the return is `SMAP' | ||
366 | jne bail820 # fall to e801 if it fails | ||
367 | |||
368 | # cmpl $1, 16(%di) # is this usable memory? | ||
369 | # jne again820 | ||
370 | |||
371 | # If this is usable memory, we save it by simply advancing %di by | ||
372 | # sizeof(e820rec). | ||
373 | # | ||
374 | good820: | ||
375 | movb (E820NR), %al # up to 128 entries | ||
376 | cmpb $E820MAX, %al | ||
377 | jae bail820 | ||
378 | |||
379 | incb (E820NR) | ||
380 | movw %di, %ax | ||
381 | addw $20, %ax | ||
382 | movw %ax, %di | ||
383 | again820: | ||
384 | cmpl $0, %ebx # check to see if | ||
385 | jne jmpe820 # %ebx is set to EOF | ||
386 | bail820: | ||
387 | |||
388 | |||
389 | # method E801H: | ||
390 | # memory size is in 1k chunksizes, to avoid confusing loadlin. | ||
391 | # we store the 0xe801 memory size in a completely different place, | ||
392 | # because it will most likely be longer than 16 bits. | ||
393 | # (use 1e0 because that's what Larry Augustine uses in his | ||
394 | # alternative new memory detection scheme, and it's sensible | ||
395 | # to write everything into the same place.) | ||
396 | |||
397 | meme801: | ||
398 | stc # fix to work around buggy | ||
399 | xorw %cx,%cx # BIOSes which don't clear/set | ||
400 | xorw %dx,%dx # carry on pass/error of | ||
401 | # e801h memory size call | ||
402 | # or merely pass cx,dx though | ||
403 | # without changing them. | ||
404 | movw $0xe801, %ax | ||
405 | int $0x15 | ||
406 | jc mem88 | ||
407 | |||
408 | cmpw $0x0, %cx # Kludge to handle BIOSes | ||
409 | jne e801usecxdx # which report their extended | ||
410 | cmpw $0x0, %dx # memory in AX/BX rather than | ||
411 | jne e801usecxdx # CX/DX. The spec I have read | ||
412 | movw %ax, %cx # seems to indicate AX/BX | ||
413 | movw %bx, %dx # are more reasonable anyway... | ||
414 | |||
415 | e801usecxdx: | ||
416 | andl $0xffff, %edx # clear sign extend | ||
417 | shll $6, %edx # and go from 64k to 1k chunks | ||
418 | movl %edx, (0x1e0) # store extended memory size | ||
419 | andl $0xffff, %ecx # clear sign extend | ||
420 | addl %ecx, (0x1e0) # and add lower memory into | ||
421 | # total size. | ||
422 | |||
423 | # Ye Olde Traditional Methode. Returns the memory size (up to 16mb or | ||
424 | # 64mb, depending on the bios) in ax. | ||
425 | mem88: | ||
426 | |||
427 | #endif | ||
428 | movb $0x88, %ah | ||
429 | int $0x15 | ||
430 | movw %ax, (2) | ||
431 | |||
432 | # Set the keyboard repeat rate to the max | ||
433 | movw $0x0305, %ax | ||
434 | xorw %bx, %bx | ||
435 | int $0x16 | ||
436 | |||
437 | # Check for video adapter and its parameters and allow the | ||
438 | # user to browse video modes. | ||
439 | call video # NOTE: we need %ds pointing | ||
440 | # to bootsector | ||
441 | |||
442 | # Get hd0 data... | ||
443 | xorw %ax, %ax | ||
444 | movw %ax, %ds | ||
445 | ldsw (4 * 0x41), %si | ||
446 | movw %cs, %ax # aka SETUPSEG | ||
447 | subw $DELTA_INITSEG, %ax # aka INITSEG | ||
448 | pushw %ax | ||
449 | movw %ax, %es | ||
450 | movw $0x0080, %di | ||
451 | movw $0x10, %cx | ||
452 | pushw %cx | ||
453 | cld | ||
454 | rep | ||
455 | movsb | ||
456 | # Get hd1 data... | ||
457 | xorw %ax, %ax | ||
458 | movw %ax, %ds | ||
459 | ldsw (4 * 0x46), %si | ||
460 | popw %cx | ||
461 | popw %es | ||
462 | movw $0x0090, %di | ||
463 | rep | ||
464 | movsb | ||
465 | # Check that there IS a hd1 :-) | ||
466 | movw $0x01500, %ax | ||
467 | movb $0x81, %dl | ||
468 | int $0x13 | ||
469 | jc no_disk1 | ||
470 | |||
471 | cmpb $3, %ah | ||
472 | je is_disk1 | ||
473 | |||
474 | no_disk1: | ||
475 | movw %cs, %ax # aka SETUPSEG | ||
476 | subw $DELTA_INITSEG, %ax # aka INITSEG | ||
477 | movw %ax, %es | ||
478 | movw $0x0090, %di | ||
479 | movw $0x10, %cx | ||
480 | xorw %ax, %ax | ||
481 | cld | ||
482 | rep | ||
483 | stosb | ||
484 | is_disk1: | ||
485 | |||
486 | # Check for PS/2 pointing device | ||
487 | movw %cs, %ax # aka SETUPSEG | ||
488 | subw $DELTA_INITSEG, %ax # aka INITSEG | ||
489 | movw %ax, %ds | ||
490 | movb $0, (0x1ff) # default is no pointing device | ||
491 | int $0x11 # int 0x11: equipment list | ||
492 | testb $0x04, %al # check if mouse installed | ||
493 | jz no_psmouse | ||
494 | |||
495 | movb $0xAA, (0x1ff) # device present | ||
496 | no_psmouse: | ||
497 | |||
498 | #include "../../i386/boot/edd.S" | ||
499 | |||
500 | # Now we want to move to protected mode ... | ||
501 | cmpw $0, %cs:realmode_swtch | ||
502 | jz rmodeswtch_normal | ||
503 | |||
504 | lcall *%cs:realmode_swtch | ||
505 | |||
506 | jmp rmodeswtch_end | ||
507 | |||
508 | rmodeswtch_normal: | ||
509 | pushw %cs | ||
510 | call default_switch | ||
511 | |||
512 | rmodeswtch_end: | ||
513 | # we get the code32 start address and modify the below 'jmpi' | ||
514 | # (loader may have changed it) | ||
515 | movl %cs:code32_start, %eax | ||
516 | movl %eax, %cs:code32 | ||
517 | |||
518 | # Now we move the system to its rightful place ... but we check if we have a | ||
519 | # big-kernel. In that case we *must* not move it ... | ||
520 | testb $LOADED_HIGH, %cs:loadflags | ||
521 | jz do_move0 # .. then we have a normal low | ||
522 | # loaded zImage | ||
523 | # .. or else we have a high | ||
524 | # loaded bzImage | ||
525 | jmp end_move # ... and we skip moving | ||
526 | |||
527 | do_move0: | ||
528 | movw $0x100, %ax # start of destination segment | ||
529 | movw %cs, %bp # aka SETUPSEG | ||
530 | subw $DELTA_INITSEG, %bp # aka INITSEG | ||
531 | movw %cs:start_sys_seg, %bx # start of source segment | ||
532 | cld | ||
533 | do_move: | ||
534 | movw %ax, %es # destination segment | ||
535 | incb %ah # instead of add ax,#0x100 | ||
536 | movw %bx, %ds # source segment | ||
537 | addw $0x100, %bx | ||
538 | subw %di, %di | ||
539 | subw %si, %si | ||
540 | movw $0x800, %cx | ||
541 | rep | ||
542 | movsw | ||
543 | cmpw %bp, %bx # assume start_sys_seg > 0x200, | ||
544 | # so we will perhaps read one | ||
545 | # page more than needed, but | ||
546 | # never overwrite INITSEG | ||
547 | # because destination is a | ||
548 | # minimum one page below source | ||
549 | jb do_move | ||
550 | |||
551 | end_move: | ||
552 | # then we load the segment descriptors | ||
553 | movw %cs, %ax # aka SETUPSEG | ||
554 | movw %ax, %ds | ||
555 | |||
556 | # Check whether we need to be downward compatible with version <=201 | ||
557 | cmpl $0, cmd_line_ptr | ||
558 | jne end_move_self # loader uses version >=202 features | ||
559 | cmpb $0x20, type_of_loader | ||
560 | je end_move_self # bootsect loader, we know of it | ||
561 | |||
562 | # Boot loader doesnt support boot protocol version 2.02. | ||
563 | # If we have our code not at 0x90000, we need to move it there now. | ||
564 | # We also then need to move the params behind it (commandline) | ||
565 | # Because we would overwrite the code on the current IP, we move | ||
566 | # it in two steps, jumping high after the first one. | ||
567 | movw %cs, %ax | ||
568 | cmpw $SETUPSEG, %ax | ||
569 | je end_move_self | ||
570 | |||
571 | cli # make sure we really have | ||
572 | # interrupts disabled ! | ||
573 | # because after this the stack | ||
574 | # should not be used | ||
575 | subw $DELTA_INITSEG, %ax # aka INITSEG | ||
576 | movw %ss, %dx | ||
577 | cmpw %ax, %dx | ||
578 | jb move_self_1 | ||
579 | |||
580 | addw $INITSEG, %dx | ||
581 | subw %ax, %dx # this will go into %ss after | ||
582 | # the move | ||
583 | move_self_1: | ||
584 | movw %ax, %ds | ||
585 | movw $INITSEG, %ax # real INITSEG | ||
586 | movw %ax, %es | ||
587 | movw %cs:setup_move_size, %cx | ||
588 | std # we have to move up, so we use | ||
589 | # direction down because the | ||
590 | # areas may overlap | ||
591 | movw %cx, %di | ||
592 | decw %di | ||
593 | movw %di, %si | ||
594 | subw $move_self_here+0x200, %cx | ||
595 | rep | ||
596 | movsb | ||
597 | ljmp $SETUPSEG, $move_self_here | ||
598 | |||
599 | move_self_here: | ||
600 | movw $move_self_here+0x200, %cx | ||
601 | rep | ||
602 | movsb | ||
603 | movw $SETUPSEG, %ax | ||
604 | movw %ax, %ds | ||
605 | movw %dx, %ss | ||
606 | end_move_self: # now we are at the right place | ||
607 | lidt idt_48 # load idt with 0,0 | ||
608 | xorl %eax, %eax # Compute gdt_base | ||
609 | movw %ds, %ax # (Convert %ds:gdt to a linear ptr) | ||
610 | shll $4, %eax | ||
611 | addl $gdt, %eax | ||
612 | movl %eax, (gdt_48+2) | ||
613 | lgdt gdt_48 # load gdt with whatever is | ||
614 | # appropriate | ||
615 | |||
616 | # that was painless, now we enable a20 | ||
617 | call empty_8042 | ||
618 | |||
619 | movb $0xD1, %al # command write | ||
620 | outb %al, $0x64 | ||
621 | call empty_8042 | ||
622 | |||
623 | movb $0xDF, %al # A20 on | ||
624 | outb %al, $0x60 | ||
625 | call empty_8042 | ||
626 | |||
627 | # | ||
628 | # You must preserve the other bits here. Otherwise embarrasing things | ||
629 | # like laptops powering off on boot happen. Corrected version by Kira | ||
630 | # Brown from Linux 2.2 | ||
631 | # | ||
632 | inb $0x92, %al # | ||
633 | orb $02, %al # "fast A20" version | ||
634 | outb %al, $0x92 # some chips have only this | ||
635 | |||
636 | # wait until a20 really *is* enabled; it can take a fair amount of | ||
637 | # time on certain systems; Toshiba Tecras are known to have this | ||
638 | # problem. The memory location used here (0x200) is the int 0x80 | ||
639 | # vector, which should be safe to use. | ||
640 | |||
641 | xorw %ax, %ax # segment 0x0000 | ||
642 | movw %ax, %fs | ||
643 | decw %ax # segment 0xffff (HMA) | ||
644 | movw %ax, %gs | ||
645 | a20_wait: | ||
646 | incw %ax # unused memory location <0xfff0 | ||
647 | movw %ax, %fs:(0x200) # we use the "int 0x80" vector | ||
648 | cmpw %gs:(0x210), %ax # and its corresponding HMA addr | ||
649 | je a20_wait # loop until no longer aliased | ||
650 | |||
651 | # make sure any possible coprocessor is properly reset.. | ||
652 | xorw %ax, %ax | ||
653 | outb %al, $0xf0 | ||
654 | call delay | ||
655 | |||
656 | outb %al, $0xf1 | ||
657 | call delay | ||
658 | |||
659 | # well, that went ok, I hope. Now we mask all interrupts - the rest | ||
660 | # is done in init_IRQ(). | ||
661 | movb $0xFF, %al # mask all interrupts for now | ||
662 | outb %al, $0xA1 | ||
663 | call delay | ||
664 | |||
665 | movb $0xFB, %al # mask all irq's but irq2 which | ||
666 | outb %al, $0x21 # is cascaded | ||
667 | |||
668 | # Well, that certainly wasn't fun :-(. Hopefully it works, and we don't | ||
669 | # need no steenking BIOS anyway (except for the initial loading :-). | ||
670 | # The BIOS-routine wants lots of unnecessary data, and it's less | ||
671 | # "interesting" anyway. This is how REAL programmers do it. | ||
672 | # | ||
673 | # Well, now's the time to actually move into protected mode. To make | ||
674 | # things as simple as possible, we do no register set-up or anything, | ||
675 | # we let the gnu-compiled 32-bit programs do that. We just jump to | ||
676 | # absolute address 0x1000 (or the loader supplied one), | ||
677 | # in 32-bit protected mode. | ||
678 | # | ||
679 | # Note that the short jump isn't strictly needed, although there are | ||
680 | # reasons why it might be a good idea. It won't hurt in any case. | ||
681 | movw $1, %ax # protected mode (PE) bit | ||
682 | lmsw %ax # This is it! | ||
683 | jmp flush_instr | ||
684 | |||
685 | flush_instr: | ||
686 | xorw %bx, %bx # Flag to indicate a boot | ||
687 | xorl %esi, %esi # Pointer to real-mode code | ||
688 | movw %cs, %si | ||
689 | subw $DELTA_INITSEG, %si | ||
690 | shll $4, %esi # Convert to 32-bit pointer | ||
691 | # NOTE: For high loaded big kernels we need a | ||
692 | # jmpi 0x100000,__KERNEL_CS | ||
693 | # | ||
694 | # but we yet haven't reloaded the CS register, so the default size | ||
695 | # of the target offset still is 16 bit. | ||
696 | # However, using an operand prefix (0x66), the CPU will properly | ||
697 | # take our 48 bit far pointer. (INTeL 80386 Programmer's Reference | ||
698 | # Manual, Mixing 16-bit and 32-bit code, page 16-6) | ||
699 | |||
700 | .byte 0x66, 0xea # prefix + jmpi-opcode | ||
701 | code32: .long 0x1000 # will be set to 0x100000 | ||
702 | # for big kernels | ||
703 | .word __KERNEL_CS | ||
704 | |||
705 | # Here's a bunch of information about your current kernel.. | ||
706 | kernel_version: .ascii UTS_RELEASE | ||
707 | .ascii " (" | ||
708 | .ascii LINUX_COMPILE_BY | ||
709 | .ascii "@" | ||
710 | .ascii LINUX_COMPILE_HOST | ||
711 | .ascii ") " | ||
712 | .ascii UTS_VERSION | ||
713 | .byte 0 | ||
714 | |||
715 | # This is the default real mode switch routine. | ||
716 | # to be called just before protected mode transition | ||
717 | default_switch: | ||
718 | cli # no interrupts allowed ! | ||
719 | movb $0x80, %al # disable NMI for bootup | ||
720 | # sequence | ||
721 | outb %al, $0x70 | ||
722 | lret | ||
723 | |||
724 | |||
725 | # This routine checks that the keyboard command queue is empty | ||
726 | # (after emptying the output buffers) | ||
727 | # | ||
728 | # Some machines have delusions that the keyboard buffer is always full | ||
729 | # with no keyboard attached... | ||
730 | # | ||
731 | # If there is no keyboard controller, we will usually get 0xff | ||
732 | # to all the reads. With each IO taking a microsecond and | ||
733 | # a timeout of 100,000 iterations, this can take about half a | ||
734 | # second ("delay" == outb to port 0x80). That should be ok, | ||
735 | # and should also be plenty of time for a real keyboard controller | ||
736 | # to empty. | ||
737 | # | ||
738 | |||
739 | empty_8042: | ||
740 | pushl %ecx | ||
741 | movl $100000, %ecx | ||
742 | |||
743 | empty_8042_loop: | ||
744 | decl %ecx | ||
745 | jz empty_8042_end_loop | ||
746 | |||
747 | call delay | ||
748 | |||
749 | inb $0x64, %al # 8042 status port | ||
750 | testb $1, %al # output buffer? | ||
751 | jz no_output | ||
752 | |||
753 | call delay | ||
754 | inb $0x60, %al # read it | ||
755 | jmp empty_8042_loop | ||
756 | |||
757 | no_output: | ||
758 | testb $2, %al # is input buffer full? | ||
759 | jnz empty_8042_loop # yes - loop | ||
760 | empty_8042_end_loop: | ||
761 | popl %ecx | ||
762 | ret | ||
763 | |||
764 | # Read the cmos clock. Return the seconds in al | ||
765 | gettime: | ||
766 | pushw %cx | ||
767 | movb $0x02, %ah | ||
768 | int $0x1a | ||
769 | movb %dh, %al # %dh contains the seconds | ||
770 | andb $0x0f, %al | ||
771 | movb %dh, %ah | ||
772 | movb $0x04, %cl | ||
773 | shrb %cl, %ah | ||
774 | aad | ||
775 | popw %cx | ||
776 | ret | ||
777 | |||
778 | # Delay is needed after doing I/O | ||
779 | delay: | ||
780 | outb %al,$0x80 | ||
781 | ret | ||
782 | |||
783 | # Descriptor tables | ||
784 | gdt: | ||
785 | .word 0, 0, 0, 0 # dummy | ||
786 | |||
787 | .word 0, 0, 0, 0 # unused | ||
788 | |||
789 | .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb) | ||
790 | .word 0 # base address = 0 | ||
791 | .word 0x9A00 # code read/exec | ||
792 | .word 0x00CF # granularity = 4096, 386 | ||
793 | # (+5th nibble of limit) | ||
794 | |||
795 | .word 0xFFFF # 4Gb - (0x100000*0x1000 = 4Gb) | ||
796 | .word 0 # base address = 0 | ||
797 | .word 0x9200 # data read/write | ||
798 | .word 0x00CF # granularity = 4096, 386 | ||
799 | # (+5th nibble of limit) | ||
800 | gdt_end: | ||
801 | idt_48: | ||
802 | .word 0 # idt limit = 0 | ||
803 | .word 0, 0 # idt base = 0L | ||
804 | gdt_48: | ||
805 | .word gdt_end-gdt-1 # gdt limit | ||
806 | .word 0, 0 # gdt base (filled in later) | ||
807 | |||
808 | # Include video setup & detection code | ||
809 | |||
810 | #include "../../i386/boot/video.S" | ||
811 | |||
812 | # Setup signature -- must be last | ||
813 | setup_sig1: .word SIG1 | ||
814 | setup_sig2: .word SIG2 | ||
815 | |||
816 | # After this point, there is some free space which is used by the video mode | ||
817 | # handling code to store the temporary mode table (not used by the kernel). | ||
818 | |||
819 | modelist: | ||
820 | |||
821 | .text | ||
822 | endtext: | ||
823 | .data | ||
824 | enddata: | ||
825 | .bss | ||
826 | endbss: | ||
diff --git a/arch/x86_64/boot/tools/build.c b/arch/x86_64/boot/tools/build.c deleted file mode 100644 index eae86691709a..000000000000 --- a/arch/x86_64/boot/tools/build.c +++ /dev/null | |||
@@ -1,185 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1991, 1992 Linus Torvalds | ||
3 | * Copyright (C) 1997 Martin Mares | ||
4 | */ | ||
5 | |||
6 | /* | ||
7 | * This file builds a disk-image from three different files: | ||
8 | * | ||
9 | * - bootsect: compatibility mbr which prints an error message if | ||
10 | * someone tries to boot the kernel directly. | ||
11 | * - setup: 8086 machine code, sets up system parm | ||
12 | * - system: 80386 code for actual system | ||
13 | * | ||
14 | * It does some checking that all files are of the correct type, and | ||
15 | * just writes the result to stdout, removing headers and padding to | ||
16 | * the right amount. It also writes some system data to stderr. | ||
17 | */ | ||
18 | |||
19 | /* | ||
20 | * Changes by tytso to allow root device specification | ||
21 | * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996 | ||
22 | * Cross compiling fixes by Gertjan van Wingerde, July 1996 | ||
23 | * Rewritten by Martin Mares, April 1997 | ||
24 | */ | ||
25 | |||
26 | #include <stdio.h> | ||
27 | #include <string.h> | ||
28 | #include <stdlib.h> | ||
29 | #include <stdarg.h> | ||
30 | #include <sys/types.h> | ||
31 | #include <sys/stat.h> | ||
32 | #include <sys/sysmacros.h> | ||
33 | #include <unistd.h> | ||
34 | #include <fcntl.h> | ||
35 | #include <asm/boot.h> | ||
36 | |||
37 | typedef unsigned char byte; | ||
38 | typedef unsigned short word; | ||
39 | typedef unsigned long u32; | ||
40 | |||
41 | #define DEFAULT_MAJOR_ROOT 0 | ||
42 | #define DEFAULT_MINOR_ROOT 0 | ||
43 | |||
44 | /* Minimal number of setup sectors (see also bootsect.S) */ | ||
45 | #define SETUP_SECTS 4 | ||
46 | |||
47 | byte buf[1024]; | ||
48 | int fd; | ||
49 | int is_big_kernel; | ||
50 | |||
51 | void die(const char * str, ...) | ||
52 | { | ||
53 | va_list args; | ||
54 | va_start(args, str); | ||
55 | vfprintf(stderr, str, args); | ||
56 | fputc('\n', stderr); | ||
57 | exit(1); | ||
58 | } | ||
59 | |||
60 | void file_open(const char *name) | ||
61 | { | ||
62 | if ((fd = open(name, O_RDONLY, 0)) < 0) | ||
63 | die("Unable to open `%s': %m", name); | ||
64 | } | ||
65 | |||
66 | void usage(void) | ||
67 | { | ||
68 | die("Usage: build [-b] bootsect setup system [rootdev] [> image]"); | ||
69 | } | ||
70 | |||
71 | int main(int argc, char ** argv) | ||
72 | { | ||
73 | unsigned int i, c, sz, setup_sectors; | ||
74 | u32 sys_size; | ||
75 | byte major_root, minor_root; | ||
76 | struct stat sb; | ||
77 | |||
78 | if (argc > 2 && !strcmp(argv[1], "-b")) | ||
79 | { | ||
80 | is_big_kernel = 1; | ||
81 | argc--, argv++; | ||
82 | } | ||
83 | if ((argc < 4) || (argc > 5)) | ||
84 | usage(); | ||
85 | if (argc > 4) { | ||
86 | if (!strcmp(argv[4], "CURRENT")) { | ||
87 | if (stat("/", &sb)) { | ||
88 | perror("/"); | ||
89 | die("Couldn't stat /"); | ||
90 | } | ||
91 | major_root = major(sb.st_dev); | ||
92 | minor_root = minor(sb.st_dev); | ||
93 | } else if (strcmp(argv[4], "FLOPPY")) { | ||
94 | if (stat(argv[4], &sb)) { | ||
95 | perror(argv[4]); | ||
96 | die("Couldn't stat root device."); | ||
97 | } | ||
98 | major_root = major(sb.st_rdev); | ||
99 | minor_root = minor(sb.st_rdev); | ||
100 | } else { | ||
101 | major_root = 0; | ||
102 | minor_root = 0; | ||
103 | } | ||
104 | } else { | ||
105 | major_root = DEFAULT_MAJOR_ROOT; | ||
106 | minor_root = DEFAULT_MINOR_ROOT; | ||
107 | } | ||
108 | fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root); | ||
109 | |||
110 | file_open(argv[1]); | ||
111 | i = read(fd, buf, sizeof(buf)); | ||
112 | fprintf(stderr,"Boot sector %d bytes.\n",i); | ||
113 | if (i != 512) | ||
114 | die("Boot block must be exactly 512 bytes"); | ||
115 | if (buf[510] != 0x55 || buf[511] != 0xaa) | ||
116 | die("Boot block hasn't got boot flag (0xAA55)"); | ||
117 | buf[508] = minor_root; | ||
118 | buf[509] = major_root; | ||
119 | if (write(1, buf, 512) != 512) | ||
120 | die("Write call failed"); | ||
121 | close (fd); | ||
122 | |||
123 | file_open(argv[2]); /* Copy the setup code */ | ||
124 | for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c ) | ||
125 | if (write(1, buf, c) != c) | ||
126 | die("Write call failed"); | ||
127 | if (c != 0) | ||
128 | die("read-error on `setup'"); | ||
129 | close (fd); | ||
130 | |||
131 | setup_sectors = (i + 511) / 512; /* Pad unused space with zeros */ | ||
132 | /* for compatibility with ancient versions of LILO. */ | ||
133 | if (setup_sectors < SETUP_SECTS) | ||
134 | setup_sectors = SETUP_SECTS; | ||
135 | fprintf(stderr, "Setup is %d bytes.\n", i); | ||
136 | memset(buf, 0, sizeof(buf)); | ||
137 | while (i < setup_sectors * 512) { | ||
138 | c = setup_sectors * 512 - i; | ||
139 | if (c > sizeof(buf)) | ||
140 | c = sizeof(buf); | ||
141 | if (write(1, buf, c) != c) | ||
142 | die("Write call failed"); | ||
143 | i += c; | ||
144 | } | ||
145 | |||
146 | file_open(argv[3]); | ||
147 | if (fstat (fd, &sb)) | ||
148 | die("Unable to stat `%s': %m", argv[3]); | ||
149 | sz = sb.st_size; | ||
150 | fprintf (stderr, "System is %d kB\n", sz/1024); | ||
151 | sys_size = (sz + 15) / 16; | ||
152 | if (!is_big_kernel && sys_size > DEF_SYSSIZE) | ||
153 | die("System is too big. Try using bzImage or modules."); | ||
154 | while (sz > 0) { | ||
155 | int l, n; | ||
156 | |||
157 | l = (sz > sizeof(buf)) ? sizeof(buf) : sz; | ||
158 | if ((n=read(fd, buf, l)) != l) { | ||
159 | if (n < 0) | ||
160 | die("Error reading %s: %m", argv[3]); | ||
161 | else | ||
162 | die("%s: Unexpected EOF", argv[3]); | ||
163 | } | ||
164 | if (write(1, buf, l) != l) | ||
165 | die("Write failed"); | ||
166 | sz -= l; | ||
167 | } | ||
168 | close(fd); | ||
169 | |||
170 | if (lseek(1, 497, SEEK_SET) != 497) /* Write sizes to the bootsector */ | ||
171 | die("Output: seek failed"); | ||
172 | buf[0] = setup_sectors; | ||
173 | if (write(1, buf, 1) != 1) | ||
174 | die("Write of setup sector count failed"); | ||
175 | if (lseek(1, 500, SEEK_SET) != 500) | ||
176 | die("Output: seek failed"); | ||
177 | buf[0] = (sys_size & 0xff); | ||
178 | buf[1] = ((sys_size >> 8) & 0xff); | ||
179 | buf[2] = ((sys_size >> 16) & 0xff); | ||
180 | buf[3] = ((sys_size >> 24) & 0xff); | ||
181 | if (write(1, buf, 4) != 4) | ||
182 | die("Write of image length failed"); | ||
183 | |||
184 | return 0; /* Everything is OK */ | ||
185 | } | ||