Chinaunix首页 | 论坛 | 博客
  • 博客访问: 469961
  • 博文数量: 164
  • 博客积分: 4024
  • 博客等级: 上校
  • 技术积分: 1580
  • 用 户 组: 普通用户
  • 注册时间: 2009-10-10 16:27
文章分类

全部博文(164)

文章存档

2011年(1)

2010年(108)

2009年(55)

我的朋友

分类:

2010-06-28 10:12:22

到此loader的使命已经完成:加载内核,跳进保护模式。下面就要把工作交给内核了。这个主要讲下转交控制权,本来控制权在loader,说转交控制权也就是jmp到内核执行呵呵。不过内核是采用ELF文件格式,所以我们首先要根据ELF文件信息把kernel.bin转移到正确的位置。
接着上阶段步骤开始:
用光盘中工具ELFParser打开kernel.bin得到ELF header,program header
 
------------ ELF Header ---------------
e_ident              7Fh, "ELF", 1h, 1h, 1h, ...
e_type                2    Executable file
e_machine             3    80386
e_version             1
e_entry         8048060 H    Entry point.
e_phoff              34 H
e_shoff              A8 H
e_flags               0
e_ehsize             34 H
e_phentsize          20 H
e_phnum               1
e_shentsize          28 H
e_shnum               4 H
e_shstrndx            3 H
------------- Program Header 0 -------------
p_type                1 H    PT_LOAD
p_offset              0 H
p_vaddr         8048000 H
p_paddr         8048000 H
p_filesz             6D H
p_memsz              6D H
p_flags               5 H
p_align            1000 H
------------- Section Header 0 -------------
sh_name               0 H   
sh_type               0 H    SHT_NULL
sh_flags              0 H    Unknown
sh_addr               0 H    Position in Mem.
sh_offset             0 H    Position in file.
sh_size               0 H
sh_link               0 H
sh_info               0 H
sh_addralign          0 H
sh_entsize            0 H
------------- Section Header 1 -------------
sh_name               B H    .text
sh_type               1 H    SHT_PROGBITS
sh_flags              6 H    SHF_ALLOC & SHF_EXECINSTR
sh_addr         8048060 H    Position in Mem.
sh_offset            60 H    Position in file.
sh_size               D H
sh_link               0 H
sh_info               0 H
sh_addralign         10 H
sh_entsize            0 H
------------- Section Header 2 -------------
sh_name              11 H    .comment
sh_type               1 H    SHT_PROGBITS
sh_flags              0 H    Unknown
sh_addr               0 H    Position in Mem.
sh_offset            6D H    Position in file.
sh_size              1F H
sh_link               0 H
sh_info               0 H
sh_addralign          1 H
sh_entsize            0 H
------------- Section Header 3 -------------
sh_name               1 H    .shstrtab
sh_type               3 H    SHT_STRTAB
sh_flags              0 H    Unknown
sh_addr               0 H    Position in Mem.
sh_offset            8C H    Position in file.
sh_size              1A H
sh_link               0 H
sh_info               0 H
sh_addralign          1 H
sh_entsize            0 H
---------------------------------------
p_addr为段在内存中的虚拟地址,我们发现他是8048000 ,内存已超过128M,所以我们需要重新定位内核
nasm -f elf -o kernel.o kernel.asm
ld -s -Ttext 0x30400 -o kernel.bin kernel.o
再重新用ELFParser看下:
 
==================================================================
C:\Documents and Settings\Administrator.CASIT-B2FCB2224\桌面\MyOS5\kernel.bin
==================================================================
 
------------ ELF Header ---------------
e_ident              7Fh, "ELF", 1h, 1h, 1h, ...
e_type                2    Executable file
e_machine             3    80386
e_version             1
e_entry           30400 H    Entry point.
e_phoff              34 H
e_shoff             448 H
e_flags               0
e_ehsize             34 H
e_phentsize          20 H
e_phnum               1
e_shentsize          28 H
e_shnum               4 H
e_shstrndx            3 H
------------- Program Header 0 -------------
p_type                1 H    PT_LOAD
p_offset              0 H
p_vaddr           30000 H
p_paddr           30000 H
p_filesz            40D H
p_memsz             40D H
p_flags               5 H
p_align            1000 H
------------- Section Header 0 -------------
sh_name               0 H   
sh_type               0 H    SHT_NULL
sh_flags              0 H    Unknown
sh_addr               0 H    Position in Mem.
sh_offset             0 H    Position in file.
sh_size               0 H
sh_link               0 H
sh_info               0 H
sh_addralign          0 H
sh_entsize            0 H
------------- Section Header 1 -------------
sh_name               B H    .text
sh_type               1 H    SHT_PROGBITS
sh_flags              6 H    SHF_ALLOC & SHF_EXECINSTR
sh_addr           30400 H    Position in Mem.
sh_offset           400 H    Position in file.
sh_size               D H
sh_link               0 H
sh_info               0 H
sh_addralign         10 H
sh_entsize            0 H
------------- Section Header 2 -------------
sh_name              11 H    .comment
sh_type               1 H    SHT_PROGBITS
sh_flags              0 H    Unknown
sh_addr               0 H    Position in Mem.
sh_offset           40D H    Position in file.
sh_size              1F H
sh_link               0 H
sh_info               0 H
sh_addralign          1 H
sh_entsize            0 H
------------- Section Header 3 -------------
sh_name               1 H    .shstrtab
sh_type               3 H    SHT_STRTAB
sh_flags              0 H    Unknown
sh_addr               0 H    Position in Mem.
sh_offset           42C H    Position in file.
sh_size              1A H
sh_link               0 H
sh_info               0 H
sh_addralign          1 H
sh_entsize            0 H
---------------------------------------
下面就根据ELF文件信息将kernel.bin转移到正确的位置,找出每个program header,根据其信息进行内存复制。
; InitKernel ---------------------------------------------------------------------------------
; 将 KERNEL.BIN 的内容经过整理对齐后放到新的位置
; --------------------------------------------------------------------------------------------
InitKernel: ; 遍历每一个 Program Header,根据 Program Header 中的信息来确定把什么放进内存,放到什么位置,以及放多少。
 xor esi, esi
 mov cx, word [BaseOfKernelFilePhyAddr + 2Ch]; ┓ ecx <- pELFHdr->e_phnum
 movzx ecx, cx     ; ┛
 mov esi, [BaseOfKernelFilePhyAddr + 1Ch] ; esi <- pELFHdr->e_phoff
 add esi, BaseOfKernelFilePhyAddr  ; esi <- OffsetOfKernel + pELFHdr->e_phoff
.Begin:
 mov eax, [esi + 0]
 cmp eax, 0    ; PT_NULL
 jz .NoAction
 push dword [esi + 010h]  ; size ┓
 mov eax, [esi + 04h]  ; ┃
 add eax, BaseOfKernelFilePhyAddr ; ┣ ::memcpy( (void*)(pPHdr->p_vaddr),
 push eax    ; src ┃  uchCode + pPHdr->p_offset,
 push dword [esi + 08h]  ; dst ┃  pPHdr->p_filesz;
 call MemCpy    ; ┃
 add esp, 12    ; ┛
.NoAction:
 add esi, 020h   ; esi += pELFHdr->e_phentsize
 dec ecx
 jnz .Begin
 ret
; InitKernel ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
好了,跳转:
jmp SelectorFlatC:KernelEntryPointPhyAddr ; 正式进入内核 *
 
 
阅读(759) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~