2 * Copyright (c) 2008 Joshua Phillips. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
15 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
16 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * This file contains the multiboot header and the startup code
28 * that is called by the bootloader.
35 .section multiboot, "a"
37 /* multiboot header */
39 .int 0x1BADB002 /* magic */
40 .int 0x00010003 /* flags */
41 .int 0xE4514FFB /* checksum */
42 .int mb_header /* header_addr */
43 .int _text_start /* load_addr */
44 .int _edata /* load_end_addr */
45 .int _end /* bss_end_addr */
46 .int _start /* entry_addr */
47 .int 1 /* mode_type (EGA text) */
52 .section startup, "ax"
55 /* return start of free memory, after kernel image and modules */
58 /* find end of kernel image, rounded up to page boundary */
62 addl $0x1000,%eax /* round up */
65 pushl %eax /* store end of kernel image */
67 /* get multiboot flags */
69 testl $0x08,%edx /* test MBI_MODS_XXX for modules support */
70 jz 9f /* mods_XXX fields are not valid - skip */
72 /* get multiboot header fields */
73 movl 20(%ebx),%ecx /* mods_count */
74 movl 24(%ebx),%edx /* mods_addr */
76 test %ecx,%ecx /* end of module list? */
79 /* loop through module list */
80 movl 4(%edx),%eax /* mod_end */
83 addl $0x1000,%eax /* round mod_end up to page boundary */
86 /* find highest address so far */
97 /* return highest address */
103 movl $(stack + STACK_SIZE),%esp
104 subl $_virt_base,%esp
105 addl $_phys_base,%esp
109 pushl %ebx /* mb_info */
110 pushl %eax /* magic */
112 /* get start of free memory, after kernel image and modules */
113 call get_freemem_start
116 /* allocate page directory */
119 /* allocate two page tables */
135 /* point pagedir[0] -> page table
136 for addresses 0x00000000 .. 0x00400000 */
139 orl $7,%edx /* present, r/w, user */
140 movl %edx,(%eax) /* -> pd[0] */
142 /* point pagedir[768] -> page table
143 for addresses 0xC0000000 .. 0xC0400000 */
145 orl $7,%edx /* present, r/w */
146 movl %edx,768*4(%eax)
148 /* identity map the first page table */
160 /* map the second page table
161 0xC0000000 -> 0x00100000 */
166 addl $0x00100000,%edx
174 /* load page directory */
183 movl (%esp),%eax /* lower_limit */
187 /* reload stack pointer to use higher
190 subl $_phys_base,%eax
191 addl $_virt_base,%eax
201 .comm stack, STACK_SIZE