1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
/*
* setup.s is responsible for getting the system data from the BIOS,
* and putting them into the appropriate places in system memory.
* both setup.s and system has been loaded by the bootblock.
*
* 1-Jan-96 Modified by Chris Brady for use as a boot/loader for memtest-86.
*/
#define __ASSEMBLY__
#include "defs.h"
.code16
.section ".setup", "ax", @progbits
.globl start
start:
# ok, the read went well
# now we want to move to protected mode ...
cli # no interrupts allowed #
movb $0x80, %al # disable NMI for the bootup sequence
outb %al, $0x70
# The system will move itself to its rightful place.
push %cs
pop %ds
lidt idt_48 - start # load idt with 0,0
lgdt gdt_48 - start # load gdt with whatever appropriate
# that was painless, now we enable A20
call empty_8042
movb $0xD1, %al # command write
outb %al, $0x64
call empty_8042
movb $0xDF, %al # A20 on
outb %al, $0x60
call empty_8042
/*
* Note that the short jump isn't strictly needed, althought there are
* reasons why it might be a good idea. It won't hurt in any case.
*/
movw $0x0001, %ax # protected mode (PE) bit
lmsw %ax # This is it#
jmp flush_instr
flush_instr:
movw $KERNEL_DS, %ax
movw %ax, %ds
movw %ax, %es
movw %ax, %ss
movw %ax, %fs
movw %ax, %gs
data32 ljmp $KERNEL_CS, $(TSTLOAD <<4) # jmp offset 2000 of segment 0x10 (cs)
/*
* This routine checks that the keyboard command queue is empty
* (after emptying the output buffers)
*
* No timeout is used - if this hangs there is something wrong with
* the machine, and we probably couldn't proceed anyway.
*/
empty_8042:
call delay
inb $0x64, %al # 8042 status port
testb $1, %al # output buffer?
jz no_output
call delay
inb $0x60, %al # read it
jmp empty_8042
no_output:
testb $2, %al # is input buffer full?
jnz empty_8042 # yes - loop
ret
#
# Delay is needed after doing i/o
#
delay:
.word 0x00eb # jmp $+2
ret
gdt:
.word 0,0,0,0 # dummy
.word 0,0,0,0 # unused
.word 0x7FFF # limit 128mb
.word 0x0000 # base address=0
.word 0x9A00 # code read/exec
.word 0x00C0 # granularity=4096, 386
.word 0x7FFF # limit 128mb
.word 0x0000 # base address=0
.word 0x9200 # data read/write
.word 0x00C0 # granularity=4096, 386
idt_48:
.word 0 # idt limit=0
.long 0 # idt base=0L
gdt_48:
.word 0x800 # gdt limit=2048, 256 GDT entries
.word 512+gdt - start,0x9 # gdt base = 0X9xxxx
msg1:
.asciz "Setup.S\r\n"
/* Pad setup to the proper size */
.org (SETUPSECS*512)
|