📄 1127.html
字号:
DS:[0x1FF] = 0;<br>
// get equipment list<br>
// http://www.ctyme.com/intr/rb-0575.htm<br>
int11h();<br>
if (has psmouse) {<br>
DS:[0x1FF] = 0xAA;<br>
}<br>
<br>
#ifdef CONFIG_APM<br>
// check for APM BIOS<br>
<br>
DS:[0x40] = 0;<br>
// Advanced Power Management v1.0+ - installation check<br>
// http://www.ctyme.com/intr/rb-1394.htm<br>
int15h/AX=5300h(BX=0);<br>
// check both CF and BX for APM support<br>
if (APM && 32-bit protected mode interface supported) {<br>
int15h/AX=5304h(BX=0); // disconnect interface<br>
try {<br>
// clear return values first<br>
clear EBX, CX, DX, ESI, DI;<br>
// connect 32bit protect mode APM interface<br>
// http://www.ctyme.com/intr/rb-1397.htm<br>
int15h/AX=5303h(BX=0);<br>
if (supported) {<br>
DS:[0x42] = 32-bit code segment base address;<br>
DS:[0x44] = offset of entry point;<br>
DS:[0x48] = 16-bit code segment base address;<br>
DS:[0x4A] = 16-bit data segment base address;<br>
DS:[0x4E] = APM BIOS code segment length;<br>
DS:[0x52] = APM BIOS data segment length;<br>
int15h/AX=5300h(BX=0); // check again<br>
if (APM supported) {<br>
INITSET:[0x40] = APM version;<br>
INITSET:[0x4C] = APM flags;<br>
}<br>
else { // should not happen<br>
// disconnect interface<br>
int15h/AX=5304h(BX=0);<br>
}<br>
}<br>
else {<br>
// clear 32bit support<br>
INITSET:[0x4C] &= ~0x0002;<br>
}<br>
}<br>
}<br>
#endif<br>
<br>
// call mode switch<br>
if (realmode_swtch) {<br>
far realmode_swtch(); // mode switch hook<br>
}<br>
else {<br>
far default_switch(); // see below<br>
}<br>
<br>
// set code32: 0x100000 for big kernel, otherwise 0x1000<br>
(double word) code32 = code32_start;<br>
if (!(loadflags & LOADED_HIGH)) {<br>
// normal low loaded zImage<br>
move start_sys_seg:0 to (0100:0 ... CS-DELTA_INITSEG:0);<br>
// move 0x1000 bytes each time<br>
}<br>
if (CS!=SETUPSEG) {<br>
cli; // disable interrupts<br>
<br>
// store new SS in DX<br>
DX = SS;<br>
AX = CS - DELTA_INITSEG;<br>
if (DX>=AX) {<br>
DX = DX + INITSEG - AX; // i.e. SS-CS+SETUPSEG<br>
}<br>
<br>
// move CS-DELTA_INITSEG:0 to INITSEG:0 (setup_move_size bytes)<br>
// TODO: why not do this in one step?<br>
ES = INITSEG;<br>
move _DOWNWARD_ from CS-DELTA_INITSEG:setup_move_size-1 to<br>
(INITSEG:setup_move_size-1<br>
... INITSEG:move_self_here+0x200);<br>
// setup_move_size-move_self_here-0x200 bytes<br>
// INITSEG:move_self_here+0x200 = SETUPSEG:move_self_here<br>
goto SETUPSEG:move_self_here;<br>
move_self_here:<br>
move the rest to INITSEG:move_self_here+0x200-1 ... INITSEG:0;<br>
// move_self_here+0x200 bytes<br>
DS = SETUPSEG;<br>
SS = DX;<br>
}<br>
// CS==SETUPSEG is true now<br>
<br>
// Protected Mode Basics<br>
// http://x86.ddj.com/articles/pmbasics/tspec_a1_doc.htm<br>
<br>
lidt idt_48; // load idt with 0, 0;<br>
// new code added here in linux 2.4<br>
lgdt gdt_48; // load gdt with whatever appropriate;<br>
<br>
// enable A20<br>
empty_8042();<br>
outportb(0x64, 0xD1); // command write<br>
empty_8042();<br>
outportb(0x60, 0xDF); // A20 on<br>
empty_8042();<br>
<br>
#define TEST_ADDR 0x7C<br>
<br>
// test A20<br>
GS = AX = 0xFFFF;<br>
BX = 0:[TEST_ADDR];<br>
do {<br>
0:[TEST_ADDR] = ++AX;<br>
} while (AX==GS:[TEST_ADDR+0x10]);<br>
0:[TEST_ADDR] = BX;<br>
<br>
// reset coprocessor<br>
outportb(0xF0, 0);<br>
delay();<br>
outportb(0xF1, 0);<br>
delay();<br>
<br>
// reprogram the interrupts<br>
outportb(0x20, 0x11); // initialize 8259A-1<br>
delay();<br>
outportb(0xA0, 0x11); // initialize 8259A-2<br>
delay();<br>
outportb(0x21, 0x20); // start of hardware int's (0x20)<br>
delay();<br>
outportb(0xA1, 0x28); // start of hardware int's 2 (0x28)<br>
delay();<br>
outportb(0x21, 0x04); // 8259-1 is master<br>
delay();<br>
outportb(0xA1, 0x02); // 8259-2 is slave<br>
delay();<br>
outportb(0x21, 0x01); // 8086 mode<br>
delay();<br>
outportb(0xA1, 0x01); // 8086 mode<br>
delay();<br>
outportb(0xA1, 0xFF); // mask off all interrupts for now<br>
delay();<br>
outportb(0x21, 0xFB); // mask all irq's but irq2, which is cascaded<br>
<br>
// protected mode!<br>
mov ax, #1;<br>
lmsw ax;<br>
jmp flush_instr;<br>
flush_instr:<br>
xor bx, bx;<br>
}<br>
<br>
////////////////////////////////////////////////////////////////////<br>
{<br>
db 0x66, 0xea<br>
code32:<br>
dd 0x1000<br>
dw __KERNEL_CS // 0x10, defined in asm-i386/segment.h<br>
// goto 10:1000 or 10:100000<br>
<br>
kernel_version:<br>
.ascii UTS_RELEASE // defined in makefile<br>
.ascii "("<br>
.ascii LINUX_COMPILE_BY<br>
.ascii "@"<br>
.ascii LINUX_COMPILE_HOST<br>
.ascii ")"<br>
.ascii UTS_VERSION<br>
db 0<br>
}<br>
<br>
////////////////////////////////////////////////////////////////////<br>
// default real mode switch routine<br>
far default_switch()<br>
{<br>
cli;<br>
outportb(0x70, 0x80); // disable NMI<br>
}<br>
<br>
////////////////////////////////////////////////////////////////////<br>
// get called when using bootsect loader _AND_ have bzImage to load<br>
far bootsect_helper(ES)<br>
{<br>
if (bootsect_es==0) {<br>
type_of_loader = 0x20; // bootsect-loader, version 0<br>
AX = ES >> 4;<br>
CS:[bootsect_src_base+2] = AH;<br>
bootsect_es = ES;<br>
AX = ES - SYSSEG;<br>
}<br>
else {<br>
if (BX==0) { // 64K aligned<br>
// copy extended memory<br>
// http://www.ctyme.com/intr/rb-1527.htm<br>
try {<br>
int15h/AX=87h(CX=0x8000,<br>
ES:SI=CS:bootsect_gdt);<br>
}<br>
catch {<br>
bootsect_panic:<br>
prtstr("INT15 refuses to access high memory."<br>
" Giving up.");<br>
halt;<br>
}<br>
ES = bootsect_es;<br>
CS:[bootsect_dst_base+2]++;<br>
}<br>
AH = CS:[bootsect_dst_base+2] << 4;<br>
AL = 0;<br>
}<br>
}<br>
<br>
////////////////////////////////////////////////////////////////////<br>
{<br>
bootsect_gdt:<br>
.word 0, 0, 0, 0<br>
.word 0, 0, 0, 0<br>
bootsect_src:<br>
.word 0xFFFF<br>
bootsect_src_base:<br>
.byte 0, 0, 1 ! base = 0x010000<br>
.byte 0x93 ! typbyte<br>
.word 0 ! limit16, base24 =0<br>
bootsect_dst:<br>
.word 0xFFFF<br>
bootsect_dst_base:<br>
.byte 0, 0, 0x10 ! base = 0x100000<br>
.byte 0x93 ! typbyte<br>
.word 0 ! limit16, base24 =0<br>
.word 0, 0, 0, 0 ! used by BIOS<br>
.word 0, 0, 0, 0<br>
bootsect_es:<br>
.word 0<br>
}<br>
<br>
////////////////////////////////////////////////////////////////////<br>
// check that the keyboard command queue is empty<br>
empty_8042()<br>
{<br>
timeout = 0xFFFFFF; // local variable<br>
for (;;) {<br>
if (--timeout==0) return;<br>
delay();<br>
inportb(0x64, AL); // 8042 status port<br>
if (AL & 1) { // output buffer<br>
delay();<br>
inportb(0x60, .);<br>
continue;<br>
}<br>
if (!(AL & 2)) return; // input buffer<br>
}<br>
}<br>
<br>
////////////////////////////////////////////////////////////////////<br>
// read the CMOS clock, return the seconds in AL<br>
gettime()<br>
{<br>
// get real-time clock time<br>
// http://www.ctyme.com/intr/rb-2273.htm<br>
int1Ah/AH=02h(); // DH = seconds (in BCD)<br>
AL = DH & 0x0F;<br>
AH = DH >> 4;<br>
AAD;<br>
}<br>
<br>
////////////////////////////////////////////////////////////////////<br>
delay() { /* needed after doing I/O */ }<br>
<br>
////////////////////////////////////////////////////////////////////<br>
{<br>
gdt:<br>
.word 0,0,0,0 ! dummy<br>
.word 0,0,0,0 ! unused<br>
<br>
.word 0xFFFF ! 4Gb - (0x100000*0x1000 = 4Gb)<br>
.word 0x0000 ! base address=0<br>
.word 0x9A00 ! code read/exec<br>
.word 0x00CF ! granularity=4096, 386 (+5th nibble of limit)<br>
<br>
.word 0xFFFF ! 4Gb - (0x100000*0x1000 = 4Gb)<br>
.word 0x0000 ! base address=0<br>
.word 0x9200 ! data read/write<br>
.word 0x00CF ! granularity=4096, 386 (+5th nibble of limit)<br>
idt_48:<br>
.word 0 ! idt limit=0<br>
.word 0, 0 ! idt base=0L<br>
gdt_48:<br>
.word 0x800 ! gdt limit=2048, 256 GDT entries<br>
.word 512+gdt, 0x9 ! gdt base = 0x9XXXX<br>
// +512 because of bootsect<br>
}<br>
<br>
////////////////////////////////////////////////////////////////////<br>
// Included video setup & detection code "video.S"<br>
/*<br>
Positions of various video parameters passed to the kernel<br>
(see also include/linux/tty.h)<br>
CS-DELTA_INITSEG segment<br>
#define PARAM_CURSOR_POS 0x00<br>
#define PARAM_VIDEO_PAGE 0x04<br>
#define PARAM_VIDEO_MODE 0x06<br>
#define PARAM_VIDEO_COLS 0x07<br>
#define PARAM_VIDEO_EGA_BX 0x0a<br>
#define PARAM_VIDEO_LINES 0x0e<br>
#define PARAM_HAVE_VGA 0x0f<br>
#define PARAM_FONT_POINTS 0x10<br>
#define PARAM_LFB_WIDTH 0x12<br>
#define PARAM_LFB_HEIGHT 0x14<br>
#define PARAM_LFB_DEPTH 0x16<br>
#define PARAM_LFB_BASE 0x18<br>
#define PARAM_LFB_SIZE 0x1c<br>
#define PARAM_LFB_LINELENGTH 0x24<br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -