3 ; Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
4 ; (c) 2008, Peter Dinda <pdinda@northwestern.edu>
5 ; (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
6 ; (c) 2008, The V3VEE Project <http://www.v3vee.org>
9 ; This is free software. You are permitted to use,
10 ; redistribute, and modify it as specified in the file "COPYING".
12 ; A lot of this code is adapted from Kernel Toolkit 0.2
13 ; and Linux version 2.2.x, so the following copyrights apply:
15 ; Copyright (C) 1991, 1992 Linus Torvalds
16 ; modified by Drew Eckhardt
17 ; modified by Bruce Evans (bde)
18 ; adapted for Kernel Toolkit by Luigi Sgro
20 %define __BIG_KERNEL__
31 ; This is the setup header, and it must start at %cs:2 (old 0x9020:2)
33 db 'H' ; header signature
37 dw 0x0203 ; header version number (>= 0x0105)
38 ; or else old loadlin-1.5 will fail)
39 realmode_swtch: dw 0, 0 ; default_switch, SETUPSEG
40 start_sys_seg: dw SYSSEG
41 dw kernel_version ; pointing to kernel version string
42 ; above section of header is compatible
43 ; with loadlin-1.5 (header v1.5). Don't
46 type_of_loader: db 0 ; = 0, old one (LILO, Loadlin,
47 ; Bootlin, SYSLX, bootsect...)
48 ; See Documentation/i386/boot.txt for
51 ; flags, unused bits must be zero (RFU) bit within loadflags
53 ;LOADED_HIGH equ 1 ; If set, the kernel is loaded high
54 ;CAN_USE_HEAP equ 0x80 ; If set, the loader also has set
55 ; heap_end_ptr to tell how much
56 ; space behind setup.S can be used for
58 ; Only the loader knows what is free
59 ;%ifndef __BIG_KERNEL__
65 setup_move_size: dw 0x8000 ; size to move, when setup is not
66 ; loaded at 0x90000. We will move setup
67 ; to 0x90000 then just before jumping
68 ; into the kernel. However, only the
69 ; loader knows how much data behind
70 ; us also needs to be loaded.
72 code32_start: dd 0x100000 ; here loaders can put a different
73 ; start address for 32-bit code.
74 ;%ifndef __BIG_KERNEL__
75 ; dd 0x100000 ; 0x1000 = default for zImage
77 ; dd 0x100000 ; 0x100000 = default for big kernel
80 ramdisk_image: dd 0 ; address of loaded ramdisk image
81 ; Here the loader puts the 32-bit
82 ; address where it loaded the image.
83 ; This only will be read by the kernel.
85 ramdisk_size: dd 0 ; its size in bytes
90 heap_end_ptr: dw modelist+1024 ; (Header version 0x0201 or later)
91 ; space from here (exclusive) down to
92 ; end of setup code can be used by setup
93 ; for local heap purposes.
96 cmd_line_ptr: dd 0 ; (Header version 0x0202 or later)
97 ; If nonzero, a 32-bit pointer
98 ; to the kernel command line.
99 ; The command line should be
100 ; located between the start of
101 ; setup and the end of low
102 ; memory (0xa0000), or it may
103 ; get overwritten before it
104 ; gets read. If this field is
105 ; used, there is no longer
106 ; anything magical about the
107 ; 0x90000 segment; the setup
108 ; can be located anywhere in
109 ; low memory 0x10000 or higher.
111 ramdisk_max: dd 0xffffffff
112 ;kernel_alignment: dd 0x200000 ; physical addr alignment required for
113 ; protected mode relocatable kernel
114 ;%ifdef CONFIG_RELOCATABLE
115 ;relocatable_kernel: db 1
117 ;relocatable_kernel: db 0
122 ;cmdline_size: dd COMMAND_LINE_SIZE-1 ;length of the command line,
123 ;added with boot protocol
126 trampoline: call start_setup
131 %endrep ; The offset at this point is 0x240
133 ; End of setup header ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
138 ; Redefine the data segment so we can access variables
139 ; declared in this file.
143 ; Use int 15h to find out size of extended memory in KB.
144 ; Extended memory is the memory above 1MB. So by
145 ; adding 1MB to this amount, we get the total amount
146 ; of system memory. We can only detect 64MB this way,
147 ; but that's OK for now.
150 ;add ax, 1024 ; 1024 KB == 1 MB
153 add ax, 1024 ; 1024 KB == 1 MB
154 mov [mem_size_kbytes], ax
155 mov [mem_size_eblocks], bx
157 ; Kill the floppy motor.
160 ; Block interrupts, since we can't meaningfully handle them yet
161 ; and we no longer need BIOS services.
164 ; Set up IDT and GDT registers
168 ; Initialize the interrupt controllers, and enable the
173 ; Switch to protected mode!
178 ; Jump to 32 bit code.
179 jmp dword KERNEL_CS:(SETUPSEG << 4) + setup_32
184 ; set up data segment registers
192 ; Create the stack for the initial kernel thread.
193 mov esp, KERN_STACK + 4096
195 ; Build Boot_Info struct on stack.
196 ; Note that we push the fields on in reverse order,
197 ; since the stack grows downwards.
201 mov eax, [(SETUPSEG<<4)+ramdisk_size]
205 mov eax, [(SETUPSEG<<4)+ramdisk_image]
209 mov ax, [(SETUPSEG<<4)+mem_size_kbytes]
211 mov bx, [(SETUPSEG<<4)+mem_size_eblocks]
217 shl eax, 9 ; Multiply the vmm size by 512 to get byte size
218 push ebx ; size of the VMM
220 push dword 8 ; bootInfoSize
222 ; Pass pointer to Boot_Info struct as argument to kernel
226 ; Push return address to make this look like a call
228 push dword (SETUPSEG<<4)+.returnAddr
231 ; Far jump into kernel
232 jmp KERNEL_CS:ENTRY_POINT
235 ; We shouldn't return here.
243 ; Kill the floppy motor.
244 ; This code was shamelessly stolen from Linux.
252 ; Initialize master and slave PIC!
254 out 0x20, al ; ICW1 to master
256 out 0xA0, al ; ICW1 to slave
259 out 0x21, al ; ICW2 to master
262 out 0xA1, al ; ICW2 to slave
265 out 0x21, al ; ICW3 to master
268 out 0xA1, al ; ICW3 to slave
271 out 0x21, al ; ICW4 to master
273 out 0xA1, al ; ICW4 to slave
275 mov al, 0xff ; mask all ints in slave
276 out 0xA1, al ; OCW1 to slave
278 mov al, 0xfb ; mask all ints but 2 in master
279 out 0x21, al ; OCW1 to master
283 ; Linux uses this code.
284 ; The idea is that some systems issue port I/O instructions
285 ; faster than the device hardware can deal with them.
290 ; Enable the A20 address line, so we can correctly address
302 ; ----------------------------------------------------------------------
304 ; ----------------------------------------------------------------------
306 mem_size_kbytes: dw 0
307 mem_size_eblocks: dw 0
310 ; ----------------------------------------------------------------------
311 ; The GDT. Creates flat 32-bit address space for the kernel
312 ; code, data, and stack. Note that this GDT is just used
313 ; to create an environment where we can start running 32 bit
314 ; code. The kernel will create and manage its own GDT.
315 ; ----------------------------------------------------------------------
317 ; GDT initialization stuff
318 NUM_GDT_ENTRIES equ 3 ; number of entries in GDT
319 GDT_ENTRY_SZ equ 8 ; size of a single GDT entry
323 ; Descriptor 0 is not used
329 ; Descriptor 1: kernel code segment
330 dw 0xFFFF ; bytes 0 and 1 of segment size
331 dw 0x0000 ; bytes 0 and 1 of segment base address
332 db 0x00 ; byte 2 of segment base address
333 db 0x9A ; present, DPL=0, non-system, code, non-conforming,
334 ; readable, not accessed
335 db 0xCF ; granularity=page, 32 bit code, upper nibble of size
336 db 0x00 ; byte 3 of segment base address
338 ; Descriptor 2: kernel data and stack segment
339 ; NOTE: what Intel calls an "expand-up" segment
340 ; actually means that the stack will grow DOWN,
341 ; towards lower memory. So, we can use this descriptor
342 ; for both data and stack references.
343 dw 0xFFFF ; bytes 0 and 1 of segment size
344 dw 0x0000 ; bytes 0 and 1 of segment base address
345 db 0x00 ; byte 2 of segment base address
346 db 0x92 ; present, DPL=0, non-system, data, expand-up,
347 ; writable, not accessed
348 db 0xCF ; granularity=page, big, upper nibble of size
349 db 0x00 ; byte 3 of segment base address
352 dw NUM_GDT_ENTRIES*GDT_ENTRY_SZ ; limit
353 dd (SETUPSEG<<4) + GDT ; base address
359 ; Here's a bunch of information about your current kernel..
360 kernel_version: db "1.0.0VMMHack"