head大小为25KB+184B,随后才是main函数。
head创建了内核分页机制(页目录表,页表,缓冲区,GDT,IDT,并将已经执行过的代码所占内存空间覆盖)
0x0000~0x4FFF,20KB将作为页目录表
先设置寄存器ds,es,fs,gs:
.text
.globl _idt,_gdt,_pg_dir,_tmp_floppy_area
_pg_dir:
startup_32:
movl $0x10,%eax
mov %ax,%ds
mov %ax,%es
mov %ax,%fs
mov %ax,%gs
eax = 0001 0000, 即内核特权级GDT的第2项:
.word 0x07FF ! 8Mb - limit=2047 (2048*4096=8Mb)
.word 0x0000 ! base address=0
.word 0x9200 ! data read/write
.word 0x00C0 ! granularity=4096, 386
然后设置栈顶指针esp:
lss _stack_start,%esp
kernel/sched.c:
long user_stack [ PAGE_SIZE>>2 ] ;
struct {
long * a;
short b;
} stack_start = { & user_stack [PAGE_SIZE>>2] , 0x10 };
故栈的大小为一页(4KB)
经测算,其起始位置为0x1E25C
head接下来对IDT进行设置:
call setup_idt
/*
* setup_idt
*
* sets up a idt with 256 entries pointing to
* ignore_int, interrupt gates. It then loads
* idt. Everything that wants to install itself
* in the idt-table may do so themselves. Interrupts
* are enabled elsewhere, when we can be relatively
* sure everything is ok. This routine will be over-
* written by the page tables.
*/
setup_idt:
lea ignore_int,%edx
movl $0x00080000,%eax
movw %dx,%ax /* selector = 0x0008 = cs */
movw $0x8E00,%dx /* interrupt gate - dpl=0, present */
lea _idt,%edi
mov $256,%ecx
rp_s