实验12 Linux内核启动分析

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验12 Linux内核启动分析

实验目的

就boot.s和head.s了解Linux启动的部分工程

实验步骤

下载源码

分析源码

源码分析结果

head.s

# head.s contains the 32-bit startup code.

# Two L3 task multitasking. The code of tasks are in kernel area,

# just like the Linux. The kernel code is located at 0x10000.

;头文件包含32位的启动代码

;两个L3 分配多个任务,就像linux,它的任务代码在核心区域

;核心代码在0x10000的地址上

SCRN_SEL = 0x18

TSS0_SEL = 0x20

LDT0_SEL = 0x28

TSS1_SEL = 0X30

LDT1_SEL = 0x38

;将代码段和数据段的地址设为0x10

;lss传送目标指针,将目标指针内容送入

;LSS DI,string ;把段地址:偏移地址存到SS:DI.

.text

startup_32:

movl $0x10,%eax

mov %ax,%ds

# mov %ax,%es

lss init_stack,%esp;将init_stack+4送入ss,并将init_stack地址送入esp

# setup base fields of descriptors.;设置基本描述符域

call setup_idt

call setup_gdt;在完成两个设置程序的调用之后就重置所有段寄存器

movl $0x10,%eax # reload all the segment registers

mov %ax,%ds # after changing gdt.

mov %ax,%es

mov %ax,%fs

mov %ax,%gs

lss init_stack,%esp

# setup up timer 8253 chip.;设置计时器芯片8523

movb $0x36, %al

movl $0x43, %edx

outb %al, %dx #向43端口写入36

movl $11930, %eax # timer frequency 100 HZ

movl $0x40, %edx

outb %al, %dx #向40端口写入11930

movb %ah, %al

outb %al, %dx

# setup timer & system call interrupt descriptors.;

movl $0x00080000, %eax

movw $timer_interrupt, %ax;中断

movw $0x8E00, %dx

movl $0x08, %ecx # The PC default timer int.

lea idt(,%ecx,8), %esi

movl %eax,(%esi)

movl %edx,4(%esi)

movw $system_interrupt, %ax

movw $0xef00, %dx

movl $0x80, %ecx

lea idt(,%ecx,8), %esi

movl %eax,(%esi)

movl %edx,4(%esi)

# unmask the timer interrupt.

# movl $0x21, %edx

# inb %dx, %al

# andb $0xfe, %al

# outb %al, %dx

# Move to user mode (task 0)

pushfl

andl $0xffffbfff, (%esp)

popfl

movl $TSS0_SEL, %eax

ltr %ax

movl $LDT0_SEL, %eax

lldt %ax

movl $0, current

sti

pushl $0x17

pushl $init_stack

pushfl

pushl $0x0f

pushl $task0

iret

/****************************************/

setup_gdt: /****************************将lgdt_opcode的入口地址装入GDTR寄存器

lgdt lgdt_opcode

ret

将中断描述符表idt 设置成具有256 个项,并都指向ignore_int 中断门。然后加载中断* 描述符表寄存器(用lidt 指令)。真正实用的中断门以后再安装。当我们在其它地方认为一切

* 都正常时再开启中断。该子程序将会被页表覆盖掉。

*/

# 中断描述符表中的项虽然也是8 字节组成,但其格式与全局表中的不同,被称为门描述符

# (Gate Descriptor)。它的0-1,6-7 字节是偏移量,2-3 字节是选择符,4-5 字节是一些标志。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_sidt:

movl %eax,(%edi)

movl %edx,4(%edi)/////因为idt 有256项故而这里需要对其每个都加载门描述fu

addl $8,%edi

dec %ecx

jne rp_sidt

lidt lidt_opcode/********************将lidt_opcode的入口地址装入LDTR寄存器

ret

# -----------------------------------

write_char:

push %gs

pushl %ebx

# pushl %eax

mov $SCRN_SEL, %ebx

mov %bx, %gs

movl scr_loc, %bx

shl $1, %ebx

movb %al, %gs:(%ebx)

shr $1, %ebx

incl %ebx

cmpl $2000, %ebx

jb 1f

相关文档
最新文档