1.3 Transfer to 32-Bit Mode and Prepare for the Main Function
1.3.3 Open A20 and Achieve 32-Bit Addressing
The next action is to open A20 (Figure 1.19).
Opening A20 means that the CPU can be 32-bit addressing, and the maximum addressable space is 4 GB.
Linux can only support 16 MB of physical memory, but the linear address space is already 4 GB.
//code path:boot/setup.s Call empty_8042
Mov al, #0xD1 Out #0x64, al Call empty_8042 Mov al, #0xDF Out #0x60, al Call empty_8042
Tip:
A CPU has 1 MB space ranging from 0 to 0xfffff and needs 20 address lines in the real mode. A CPU will use the 32-bit address in the real mode.
Addressing in memory after opening A20
0x00000 0xFFFFF
0x00000
0xFFFFF 0xFFFFFFFF
Addressing in physical memory after opening A20
0x00000 0xFFFFF 0xFFFFFF
0x00000 0xFFFFF
Kernel
Kernel
Figure 1.19 Open A20.
In the real address mode, if the program address is more than 0xFFFFF, the CPU will roll back to the beginning of the memory for addressing. For example, every seg- ment register cannot exceed 0xFFFF, the same as IP. They both can address to 0x10FFFE at the most, which means that the program can address more than 0xFFFFF in the real address mode. Because of this, enabling the A20 address line means disabling the “roll- back” addressing mechanism of the CPU in the real mode.
1.3.4 Prepare for the Implementation of head.s in the Protected Mode
To establish the interrupt mechanism, setup.s will have to reprogram the PIC 8259A (Figure 1.20).
Tip:
8259A: 8259A is a chip designed for 8085A and 8086/8088 to control interrupt. One piece of 8259A can manage eight priority interrupt levels. 8259A can cascade to a sys- tem that can manage up to 64 priority interrupt levels in the case of no circuit adding.
Codes as follows:
mov $0x11,%al # initialization sequence(ICW1)
#ICW4needed(1),CASCADEmode,Level-triggered out %al, $0x20 # send it to 8259A-1
.word 0x00eb,0x00eb # jmp $+2, jmp $+2 out %al, $0xA0 # and to 8259A-2 .word 0x00eb,0x00eb
IRQ NO. Application
IRQ0IRQ1 IRQ2IRQ3 IRQ4IRQ5 IRQ6IRQ7 IRQ8IRQ9 IRQ10 IRQ11 IRQ12 IRQ13 IRQ14 IRQ15
0x20 (32) 0x21 (33) 0x22 (34) 0x23 (35) 0x24 (36) 0x25 (37) 0x26 (38) 0x27 (39) 0x28 (40) 0x29 (41) 0x2a (42) 0x2b (43) 0x2c (44) 0x2d (45) 0x2e (46) 0x2f (47)
8253 clock interrupt Keyboard interrupt Connect subsidiary chip Serial port 2 Serial port 1 Parallel port 2 Floppy disk driver Parallel port 1 Real time clock interrupt Reserved
Reserved
Reserved(Network API) PS/2 mouse interrupt Math coprocessor Disk interrupt Reserved
In the protected mode, int 0x00–int 0x1F are reserved for internal interrupt and exceptional interrupt by Intel, thus, IRQ must be reset.
IRQ0IRQ1
IRQ14 IRQ15
8259A 0x000x01
0x0E0x0F
IRQ0IRQ1
IRQ14 IRQ15
8259A 0x00 0x1F 0x20 0x21
0x2E0x2F
Before resetting After resetting
Interrupt request Interrupt No. Interrupt request Interrupt No.
Figure 1.20 Resetting 8259A.
mov $0x20,%al # start of hardware int’s (0x20)(ICW2) out %al, $0x21 # from 0x20-0x27
.word 0x00eb,0x00eb
mov $0x28,%al # start of hardware int’s 2 (0x28) out %al, $0xA1 # from 0x28-0x2F
.word 0x00eb,0x00eb # IR 7654 3210
mov $0x04,%al # 8259-1 is master(0000 0100)— \
out %al, $0x21 # |
.word 0x00eb,0x00eb # INT /
mov $0x02,%al # 8259-2 is slave( 010— > 2) out %al, $0xA1
.word 0x00eb,0x00eb
mov $0x01,%al # 8086 mode for both out %al, $0x21
.word 0x00eb,0x00eb out %al, $0xA1 .word 0x00eb,0x00eb
mov $0xFF,%al # mask off all interrupts for now out %al, $0x21
.word 0x00eb,0x00eb out %al, $0xA1
In the protected mode, INT 0x00–int 0x1F is reserved for internal and exception interrupt by Intel. If we do not reprogram 8259A, INT 0x00–int 0x1F will be overlapped.
For example, IRQ0 (timer interrupt) is the eighth interrupt (INT 0x08), but this interrupt is reserved as “Double Fault” in the protected mode. Hence, we must reprogram 8259A to respond to IQR0x00–IQX0x0F; in other words, IQR0x00–IQR0x0F corresponds with INT 0x20–int 0x2F in the protected mode (Figure 1.21).
Setup.s enables the CPU in the protected mode by the first two lines as follows, setting the PE bit of the CR0 Register.
//code path:boot/setup.s
mov ax,#0x0001 ! protected mode (PE) bit lmsw ax ! This is it! !
jmpi 0,8 ! jmp offset 0 of segment 8 (cs) !
Tip:
CR0 Register: No. 0 32-bit control register is used to store systemic control flags.
No. 0 bit is PE (protected mode enable) flag. If set, the CPU will work in the pro- tected mode; otherwise, in the real mode.
31 0
1 CR0 register
PE=1
CPU enters into protected mode Figure 1.21 Open the protected mode.
The key character of the CPU in the protected mode is that it executes a program according to GDT.
Note that the value of GDT in Figure 1.18 is the default setting. The way from setup.s to head.s is described in Figure 1.22.
In this code, “0” is offset address and “8” is segment selector, which is used to select GDT (global descriptor table), the No. of GDT, and the descriptor privilege level. Here, “8”
should be “1000” in binary. To understand this code, we should refer to Figure 1.23 and know that every bit of “1000” has a designated purpose.
The last two bits of “1000” means kernel privilege level, in which “11” means user privilege level. No. 3 bit of “1000” means selecting GDT; accordingly, “1” means LDT.
No. 4 bit of “1000” means No. 1 of GDT. We know that the CPU executes the program where the segment base address is 0x00000000 and the offset address is 0, which is the starting location of head.s, and which means the CPU will execute head.s.
Setup.s finishes here, and the following preparation will be done by head.s.