master
s 172 lines 3.22 KB
Raw
1 /*
2 * i386 boot code, based on qemu-bmibug.
3 *
4 * Copyright 2019 Doug Gale
5 * Copyright 2019, 2024 Linaro
6 *
7 * This work is licensed under the terms of the GNU GPL, version 2 or later.
8 * See the COPYING file in the top-level directory.
9 *
10 * SPDX-License-Identifier: GPL-2.0-or-later
11 */
12
13 .section .head
14
15 /* Multi-boot header */
16 multiboot_st:
17 .int 0x1BADB002
18 .int 0x10000
19 .int -(0x10000+0x1BADB002)
20 // Load address
21 .int __load_st
22 .int __load_st
23 .int __load_en
24 .int __bss_en
25 .int _start
26 // mode
27 .int 0
28 // width
29 .int 0
30 // height
31 .int 0
32 // depth
33 .int 0
34
35 .code32
36 .section .text
37
38 /* Kernel Entry Point */
39 .global _start
40 _start:
41 // Setup stack ASAP
42 mov $stack_end,%esp
43
44 // Load GDT ASAP
45 lgdt gdtr
46 ljmp $0x8,$.Lloadcs
47 .Lloadcs:
48 mov $0x10,%eax
49 mov %eax,%ds
50 mov %eax,%es
51 mov %eax,%fs
52 mov %eax,%gs
53 mov %eax,%ss
54
55 // Fixup the IDT to the ridiculous i386 layout
56 xor %ebx,%ebx
57 .Lnextidt:
58 mov idt_00(,%ebx,8),%eax
59 shr $16,%eax
60 movw $0x8,idt_00+2(,%ebx,8)
61 movw $0x8E00,idt_00+4(,%ebx,8)
62 movw %ax,idt_00+6(,%ebx,8)
63 add $1,%ebx
64 cmp $32,%ebx
65 jl .Lnextidt
66
67 // Load IDTR
68 push $idt_00
69 push $((32 * 8 - 1) << 16)
70 lidt 2(%esp)
71 add $8,%esp
72
73 /*
74 * Don't worry about stack frame, assume everything
75 * is garbage when we return, we won't need it.
76 */
77 call main
78
79 _exit: /* output any non-zero result in eax to isa-debug-exit device */
80 test %al, %al
81 jz 1f
82 out %ax, $0xf4
83
84 1: /* QEMU ACPI poweroff */
85 mov $0x604,%edx
86 mov $0x2000,%eax
87 out %ax,%dx
88 hlt
89 jmp 1b
90
91 /*
92 * Helper Functions
93 */
94
95 /* Output a single character to serial port */
96 .global __sys_outc
97 __sys_outc:
98 pushl %ebp
99 movl %esp, %ebp
100 out %al,$0xE9
101 movl %ebp, %esp
102 popl %ebp
103 ret
104
105
106 /* Interrupt Descriptor Table */
107
108 .section .data
109 .align 16
110
111 idt_00: .int 0, 0
112 idt_01: .int 0, 0
113 idt_02: .int 0, 0
114 idt_03: .int 0, 0
115 idt_04: .int 0, 0
116 idt_05: .int 0, 0
117 idt_06: .int 0, 0 /* intr_6_opcode, Invalid Opcode */
118 idt_07: .int 0, 0
119 idt_08: .int 0, 0
120 idt_09: .int 0, 0
121 idt_0A: .int 0, 0
122 idt_0B: .int 0, 0
123 idt_0C: .int 0, 0
124 idt_0D: .int 0, 0
125 idt_0E: .int 0, 0
126 idt_0F: .int 0, 0
127 idt_10: .int 0, 0
128 idt_11: .int 0, 0
129 idt_12: .int 0, 0
130 idt_13: .int 0, 0
131 idt_14: .int 0, 0
132 idt_15: .int 0, 0
133 idt_16: .int 0, 0
134 idt_17: .int 0, 0
135 idt_18: .int 0, 0
136 idt_19: .int 0, 0
137 idt_1A: .int 0, 0
138 idt_1B: .int 0, 0
139 idt_1C: .int 0, 0
140 idt_1D: .int 0, 0
141 idt_1E: .int 0, 0
142 idt_1F: .int 0, 0
143
144 gdt:
145 .short 0
146 gdtr:
147 .short gdt_en - gdt - 1
148 .int gdt
149
150 // Code
151 .short 0xFFFF
152 .short 0
153 .byte 0
154 .byte 0x9b
155 .byte 0xCF
156 .byte 0
157
158 // Data
159 .short 0xFFFF
160 .short 0
161 .byte 0
162 .byte 0x93
163 .byte 0xCF
164 .byte 0
165
166 gdt_en:
167
168 .section .bss
169 .align 16
170
171 stack: .space 65536
172 stack_end: