3 ; Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
4 ; Copyright (c) 2008 Jack Lange <jarusl@cs.northwestern.edu>
7 ; This is free software. You are permitted to use,
8 ; redistribute, and modify it as specified in the file "COPYING".
10 ; A lot of this code is adapted from Kernel Toolkit 0.2
11 ; and Linux version 2.2.x, so the following copyrights apply:
13 ; Copyright (C) 1991, 1992 Linus Torvalds
14 ; modified by Drew Eckhardt
15 ; modified by Bruce Evans (bde)
16 ; adapted for Kernel Toolkit by Luigi Sgro
18 %define __BIG_KERNEL__
29 ; This is the setup header, and it must start at %cs:2 (old 0x9020:2)
31 db 'H' ; header signature
35 dw 0x0203 ; header version number (>= 0x0105)
36 ; or else old loadlin-1.5 will fail)
37 realmode_swtch: dw 0, 0 ; default_switch, SETUPSEG
38 start_sys_seg: dw SYSSEG
39 dw kernel_version ; pointing to kernel version string
40 ; above section of header is compatible
41 ; with loadlin-1.5 (header v1.5). Don't
44 type_of_loader: db 0 ; = 0, old one (LILO, Loadlin,
45 ; Bootlin, SYSLX, bootsect...)
46 ; See Documentation/i386/boot.txt for
49 ; flags, unused bits must be zero (RFU) bit within loadflags
51 ;LOADED_HIGH equ 1 ; If set, the kernel is loaded high
52 ;CAN_USE_HEAP equ 0x80 ; If set, the loader also has set
53 ; heap_end_ptr to tell how much
54 ; space behind setup.S can be used for
56 ; Only the loader knows what is free
57 ;%ifndef __BIG_KERNEL__
63 setup_move_size: dw 0x8000 ; size to move, when setup is not
64 ; loaded at 0x90000. We will move setup
65 ; to 0x90000 then just before jumping
66 ; into the kernel. However, only the
67 ; loader knows how much data behind
68 ; us also needs to be loaded.
70 code32_start: dd 0x100000 ; here loaders can put a different
71 ; start address for 32-bit code.
72 ;%ifndef __BIG_KERNEL__
73 ; dd 0x100000 ; 0x1000 = default for zImage
75 ; dd 0x100000 ; 0x100000 = default for big kernel
78 ramdisk_image: dd 0 ; address of loaded ramdisk image
79 ; Here the loader puts the 32-bit
80 ; address where it loaded the image.
81 ; This only will be read by the kernel.
83 ramdisk_size: dd 0 ; its size in bytes
88 heap_end_ptr: dw modelist+1024 ; (Header version 0x0201 or later)
89 ; space from here (exclusive) down to
90 ; end of setup code can be used by setup
91 ; for local heap purposes.
94 cmd_line_ptr: dd 0 ; (Header version 0x0202 or later)
95 ; If nonzero, a 32-bit pointer
96 ; to the kernel command line.
97 ; The command line should be
98 ; located between the start of
99 ; setup and the end of low
100 ; memory (0xa0000), or it may
101 ; get overwritten before it
102 ; gets read. If this field is
103 ; used, there is no longer
104 ; anything magical about the
105 ; 0x90000 segment; the setup
106 ; can be located anywhere in
107 ; low memory 0x10000 or higher.
109 ramdisk_max: dd 0xffffffff
110 ;kernel_alignment: dd 0x200000 ; physical addr alignment required for
111 ; protected mode relocatable kernel
112 ;%ifdef CONFIG_RELOCATABLE
113 ;relocatable_kernel: db 1
115 ;relocatable_kernel: db 0
120 ;cmdline_size: dd COMMAND_LINE_SIZE-1 ;length of the command line,
121 ;added with boot protocol
124 trampoline: call start_setup
129 %endrep ; The offset at this point is 0x240
131 ; End of setup header ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
136 ; Redefine the data segment so we can access variables
137 ; declared in this file.
141 ; Use int 15h to find out size of extended memory in KB.
142 ; Extended memory is the memory above 1MB. So by
143 ; adding 1MB to this amount, we get the total amount
144 ; of system memory. We can only detect 64MB this way,
145 ; but that's OK for now.
148 ;add ax, 1024 ; 1024 KB == 1 MB
151 add ax, 1024 ; 1024 KB == 1 MB
152 mov [mem_size_kbytes], ax
153 mov [mem_size_eblocks], bx
155 ; Kill the floppy motor.
158 ; Block interrupts, since we can't meaningfully handle them yet
159 ; and we no longer need BIOS services.
162 ; Set up IDT and GDT registers
166 ; Initialize the interrupt controllers, and enable the
171 ; Switch to protected mode!
176 ; Jump to 32 bit code.
177 jmp dword KERNEL_CS:(SETUPSEG << 4) + setup_32
182 ; set up data segment registers
190 ; Create the stack for the initial kernel thread.
191 mov esp, KERN_STACK + 4096
193 ; Build Boot_Info struct on stack.
194 ; Note that we push the fields on in reverse order,
195 ; since the stack grows downwards.
199 mov eax, [(SETUPSEG<<4)+ramdisk_size]
203 mov eax, [(SETUPSEG<<4)+ramdisk_image]
207 mov ax, [(SETUPSEG<<4)+mem_size_kbytes]
209 mov bx, [(SETUPSEG<<4)+mem_size_eblocks]
215 shl eax, 9 ; Multiply the vmm size by 512 to get byte size
216 push ebx ; size of the VMM
218 push dword 8 ; bootInfoSize
220 ; Pass pointer to Boot_Info struct as argument to kernel
224 ; Push return address to make this look like a call
226 push dword (SETUPSEG<<4)+.returnAddr
229 ; Far jump into kernel
230 jmp KERNEL_CS:ENTRY_POINT
233 ; We shouldn't return here.
241 ; Kill the floppy motor.
242 ; This code was shamelessly stolen from Linux.
250 ; Initialize master and slave PIC!
252 out 0x20, al ; ICW1 to master
254 out 0xA0, al ; ICW1 to slave
257 out 0x21, al ; ICW2 to master
260 out 0xA1, al ; ICW2 to slave
263 out 0x21, al ; ICW3 to master
266 out 0xA1, al ; ICW3 to slave
269 out 0x21, al ; ICW4 to master
271 out 0xA1, al ; ICW4 to slave
273 mov al, 0xff ; mask all ints in slave
274 out 0xA1, al ; OCW1 to slave
276 mov al, 0xfb ; mask all ints but 2 in master
277 out 0x21, al ; OCW1 to master
281 ; Linux uses this code.
282 ; The idea is that some systems issue port I/O instructions
283 ; faster than the device hardware can deal with them.
288 ; Enable the A20 address line, so we can correctly address
300 ; ----------------------------------------------------------------------
302 ; ----------------------------------------------------------------------
304 mem_size_kbytes: dw 0
305 mem_size_eblocks: dw 0
308 ; ----------------------------------------------------------------------
309 ; The GDT. Creates flat 32-bit address space for the kernel
310 ; code, data, and stack. Note that this GDT is just used
311 ; to create an environment where we can start running 32 bit
312 ; code. The kernel will create and manage its own GDT.
313 ; ----------------------------------------------------------------------
315 ; GDT initialization stuff
316 NUM_GDT_ENTRIES equ 3 ; number of entries in GDT
317 GDT_ENTRY_SZ equ 8 ; size of a single GDT entry
321 ; Descriptor 0 is not used
327 ; Descriptor 1: kernel code segment
328 dw 0xFFFF ; bytes 0 and 1 of segment size
329 dw 0x0000 ; bytes 0 and 1 of segment base address
330 db 0x00 ; byte 2 of segment base address
331 db 0x9A ; present, DPL=0, non-system, code, non-conforming,
332 ; readable, not accessed
333 db 0xCF ; granularity=page, 32 bit code, upper nibble of size
334 db 0x00 ; byte 3 of segment base address
336 ; Descriptor 2: kernel data and stack segment
337 ; NOTE: what Intel calls an "expand-up" segment
338 ; actually means that the stack will grow DOWN,
339 ; towards lower memory. So, we can use this descriptor
340 ; for both data and stack references.
341 dw 0xFFFF ; bytes 0 and 1 of segment size
342 dw 0x0000 ; bytes 0 and 1 of segment base address
343 db 0x00 ; byte 2 of segment base address
344 db 0x92 ; present, DPL=0, non-system, data, expand-up,
345 ; writable, not accessed
346 db 0xCF ; granularity=page, big, upper nibble of size
347 db 0x00 ; byte 3 of segment base address
350 dw NUM_GDT_ENTRIES*GDT_ENTRY_SZ ; limit
351 dd (SETUPSEG<<4) + GDT ; base address
357 ; Here's a bunch of information about your current kernel..
358 kernel_version: db "1.0.0VMMHack"