3 ; Copyright (c) 2001,2004 David H. Hovemeyer <daveho@cs.umd.edu>
6 ; This is free software. You are permitted to use,
7 ; redistribute, and modify it as specified in the file "COPYING".
9 ; A lot of this code is adapted from Kernel Toolkit 0.2
10 ; and Linux version 2.2.x, so the following copyrights apply:
12 ; Copyright (C) 1991, 1992 Linus Torvalds
13 ; modified by Drew Eckhardt
14 ; modified by Bruce Evans (bde)
15 ; adapted for Kernel Toolkit by Luigi Sgro
17 %define __BIG_KERNEL__
28 ; This is the setup header, and it must start at %cs:2 (old 0x9020:2)
30 db 'H' ; header signature
34 dw 0x0203 ; header version number (>= 0x0105)
35 ; or else old loadlin-1.5 will fail)
36 realmode_swtch: dw 0, 0 ; default_switch, SETUPSEG
37 start_sys_seg: dw SYSSEG
38 dw kernel_version ; pointing to kernel version string
39 ; above section of header is compatible
40 ; with loadlin-1.5 (header v1.5). Don't
43 type_of_loader: db 0 ; = 0, old one (LILO, Loadlin,
44 ; Bootlin, SYSLX, bootsect...)
45 ; See Documentation/i386/boot.txt for
48 ; flags, unused bits must be zero (RFU) bit within loadflags
50 ;LOADED_HIGH equ 1 ; If set, the kernel is loaded high
51 ;CAN_USE_HEAP equ 0x80 ; If set, the loader also has set
52 ; heap_end_ptr to tell how much
53 ; space behind setup.S can be used for
55 ; Only the loader knows what is free
56 ;%ifndef __BIG_KERNEL__
62 setup_move_size: dw 0x8000 ; size to move, when setup is not
63 ; loaded at 0x90000. We will move setup
64 ; to 0x90000 then just before jumping
65 ; into the kernel. However, only the
66 ; loader knows how much data behind
67 ; us also needs to be loaded.
69 code32_start: dd 0x100000 ; here loaders can put a different
70 ; start address for 32-bit code.
71 ;%ifndef __BIG_KERNEL__
72 ; dd 0x100000 ; 0x1000 = default for zImage
74 ; dd 0x100000 ; 0x100000 = default for big kernel
77 ramdisk_image: dd 0 ; address of loaded ramdisk image
78 ; Here the loader puts the 32-bit
79 ; address where it loaded the image.
80 ; This only will be read by the kernel.
82 ramdisk_size: dd 0 ; its size in bytes
87 heap_end_ptr: dw modelist+1024 ; (Header version 0x0201 or later)
88 ; space from here (exclusive) down to
89 ; end of setup code can be used by setup
90 ; for local heap purposes.
93 cmd_line_ptr: dd 0 ; (Header version 0x0202 or later)
94 ; If nonzero, a 32-bit pointer
95 ; to the kernel command line.
96 ; The command line should be
97 ; located between the start of
98 ; setup and the end of low
99 ; memory (0xa0000), or it may
100 ; get overwritten before it
101 ; gets read. If this field is
102 ; used, there is no longer
103 ; anything magical about the
104 ; 0x90000 segment; the setup
105 ; can be located anywhere in
106 ; low memory 0x10000 or higher.
108 ramdisk_max: dd 0xffffffff
109 ;kernel_alignment: dd 0x200000 ; physical addr alignment required for
110 ; protected mode relocatable kernel
111 ;%ifdef CONFIG_RELOCATABLE
112 ;relocatable_kernel: db 1
114 ;relocatable_kernel: db 0
119 ;cmdline_size: dd COMMAND_LINE_SIZE-1 ;length of the command line,
120 ;added with boot protocol
123 trampoline: call start_setup
128 %endrep ; The offset at this point is 0x240
130 ; End of setup header ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
135 ; Redefine the data segment so we can access variables
136 ; declared in this file.
140 ; Use int 15h to find out size of extended memory in KB.
141 ; Extended memory is the memory above 1MB. So by
142 ; adding 1MB to this amount, we get the total amount
143 ; of system memory. We can only detect 64MB this way,
144 ; but that's OK for now.
147 ;add ax, 1024 ; 1024 KB == 1 MB
150 add ax, 1024 ; 1024 KB == 1 MB
151 mov [mem_size_kbytes], ax
152 mov [mem_size_eblocks], bx
154 ; Kill the floppy motor.
157 ; Block interrupts, since we can't meaningfully handle them yet
158 ; and we no longer need BIOS services.
161 ; Set up IDT and GDT registers
165 ; Initialize the interrupt controllers, and enable the
170 ; Switch to protected mode!
175 ; Jump to 32 bit code.
176 jmp dword KERNEL_CS:(SETUPSEG << 4) + setup_32
181 ; set up data segment registers
189 ; Create the stack for the initial kernel thread.
190 mov esp, KERN_STACK + 4096
192 ; Build Boot_Info struct on stack.
193 ; Note that we push the fields on in reverse order,
194 ; since the stack grows downwards.
198 mov eax, [(SETUPSEG<<4)+ramdisk_size]
202 mov eax, [(SETUPSEG<<4)+ramdisk_image]
206 mov ax, [(SETUPSEG<<4)+mem_size_kbytes]
208 mov bx, [(SETUPSEG<<4)+mem_size_eblocks]
214 shl eax, 9 ; Multiply the vmm size by 512 to get byte size
215 push ebx ; size of the VMM
217 push dword 8 ; bootInfoSize
219 ; Pass pointer to Boot_Info struct as argument to kernel
223 ; Push return address to make this look like a call
225 push dword (SETUPSEG<<4)+.returnAddr
228 ; Far jump into kernel
229 jmp KERNEL_CS:ENTRY_POINT
232 ; We shouldn't return here.
240 ; Kill the floppy motor.
241 ; This code was shamelessly stolen from Linux.
249 ; Initialize master and slave PIC!
251 out 0x20, al ; ICW1 to master
253 out 0xA0, al ; ICW1 to slave
256 out 0x21, al ; ICW2 to master
259 out 0xA1, al ; ICW2 to slave
262 out 0x21, al ; ICW3 to master
265 out 0xA1, al ; ICW3 to slave
268 out 0x21, al ; ICW4 to master
270 out 0xA1, al ; ICW4 to slave
272 mov al, 0xff ; mask all ints in slave
273 out 0xA1, al ; OCW1 to slave
275 mov al, 0xfb ; mask all ints but 2 in master
276 out 0x21, al ; OCW1 to master
280 ; Linux uses this code.
281 ; The idea is that some systems issue port I/O instructions
282 ; faster than the device hardware can deal with them.
287 ; Enable the A20 address line, so we can correctly address
299 ; ----------------------------------------------------------------------
301 ; ----------------------------------------------------------------------
303 mem_size_kbytes: dw 0
304 mem_size_eblocks: dw 0
307 ; ----------------------------------------------------------------------
308 ; The GDT. Creates flat 32-bit address space for the kernel
309 ; code, data, and stack. Note that this GDT is just used
310 ; to create an environment where we can start running 32 bit
311 ; code. The kernel will create and manage its own GDT.
312 ; ----------------------------------------------------------------------
314 ; GDT initialization stuff
315 NUM_GDT_ENTRIES equ 3 ; number of entries in GDT
316 GDT_ENTRY_SZ equ 8 ; size of a single GDT entry
320 ; Descriptor 0 is not used
326 ; Descriptor 1: kernel code segment
327 dw 0xFFFF ; bytes 0 and 1 of segment size
328 dw 0x0000 ; bytes 0 and 1 of segment base address
329 db 0x00 ; byte 2 of segment base address
330 db 0x9A ; present, DPL=0, non-system, code, non-conforming,
331 ; readable, not accessed
332 db 0xCF ; granularity=page, 32 bit code, upper nibble of size
333 db 0x00 ; byte 3 of segment base address
335 ; Descriptor 2: kernel data and stack segment
336 ; NOTE: what Intel calls an "expand-up" segment
337 ; actually means that the stack will grow DOWN,
338 ; towards lower memory. So, we can use this descriptor
339 ; for both data and stack references.
340 dw 0xFFFF ; bytes 0 and 1 of segment size
341 dw 0x0000 ; bytes 0 and 1 of segment base address
342 db 0x00 ; byte 2 of segment base address
343 db 0x92 ; present, DPL=0, non-system, data, expand-up,
344 ; writable, not accessed
345 db 0xCF ; granularity=page, big, upper nibble of size
346 db 0x00 ; byte 3 of segment base address
349 dw NUM_GDT_ENTRIES*GDT_ENTRY_SZ ; limit
350 dd (SETUPSEG<<4) + GDT ; base address
356 ; Here's a bunch of information about your current kernel..
357 kernel_version: db "1.0.0VMMHack"