第五章--加载内核Kernel.bin

转载 2016年08月30日 22:39:59

1、Linux系统的安装 和 与宿主计算机共享文件夹

2、global 和 extern 关键字的作用

3、C调用规范(C Calling Convention)

4、ELF文件

5、Loader.bin进行加载内核——进入保护模式——向内核交出控制权


一、Linux系统的安装 和 与宿主计算机共享文件

提到Linux系统的安装,我们需要回归到第2章中2.3节——"安装虚拟Linux"。本书的作者使用的是在Virtual PC上安装的Red Hat 9.0,然后通过samba来实现与宿主机进行文件共享。开始我也是很想在Virtual PC上尝试安装和共享文件,但是n次共享文件失败后,我失去了信心,我最后实现了Linux系统与Windows系统进行相互ping IP,但是执行mount指令总是失败。最后不得已换了虚拟机,尝试使用了WMware。

1、Linux系统的安装

 Linux系统的安装按着课本中提到的几个主要步骤来完成,其他的次要步骤基本直接就Next。可以参照如下:

http://blog.csdn.net/zgh1988/article/details/7315676

2、与宿主计算机共享文件

(1)    如果你使用的是Virtual PC虚拟机,你可以尝试按着以下步骤来实现,

http://hi.baidu.com/weiloujushi/blog/item/3c3bd8586d688cda9c8204bf.html

(2) 如果你使用的是VMware虚拟机的话,首先VMware虚拟机可以通过它的VM Tools来实现文件夹的共享,所以我们要在Red Hat9.0上安装VM Tools,下面就是安装VM Tools的主要步骤,你可以尝试按着以下步骤来实现:


点击VMware菜单栏的VM--->Install VMware Tools....


执行之后,会将VMware Tools添加到cdrom中,通过cd指令进入到cdrom,然后执行ls,显示出该文件夹内所包含的文件,你会发现有存在一个WMwareTools-8.4.5-324285.tar.gz,然后执行tar -zxvfWMwareTools-8.4.5-324285.tar.gz -C /tmp,将其解压缩到/tmp文件夹内。



我们利用cd指令进入到解压缩文件,会发现在/tmp文件夹下,有vmware-tools-distrib,继续进入到vmware-tools-distrib,

然后会发现该文件夹内存在一个 vmware-install.pl,这就是该VMware-tools的安装文件。



继续执行./vmware-install.pl,进行安装。在安装好之后,需要对环境进行配置,基本上都是选择yes进行默认的环境配置,有一个选择分辨率的需要根据情况进行选择,我选择的是800*600,如果你选择的分辨率过高,可能会出现问题。



安装好VMware-tools之后,我们设置文件共享,选择VM -->Setting--> Options-->Shared Folders

设置其为Always enabled。然后将宿主计算机上的一个文件,添加到共享文件夹选项里,实现该文件的共享。



共享文件夹之后,需要在Linux系统里查找该文件,首先执行df,查看磁盘分配情况,发现最后一行为./host:/。这个就是我们所要共享的文件夹,在Linux系统中,它的路径名为 /mnt/hgfs。于是我们使用cd命令来进入该文件

cd /mnt    cd hgfs    cd Tinix 每执行一步,通过ls来查看该文件夹的情况。


二、global 和 extern 关键字的作用

global + 函数名/变量名  的作用是:向外界提供函数和变量链接接口。

extern + 函数名/变量名  的作用是:从外界引入函数和变量。

三、C调用规范(C Calling Convention)

简单的介绍一下C调用规范,有两条规定:1、后面的参数先入栈;2、由调用者(Caller)清理堆栈。

首先我们知道 函数int choose(int a, int b),a和b为形式参数,该函数存在于bar.c中。

然后在foo.asm中调用choose函数,首先需要将其参数(numlst和num2nd)入栈,我们在程序中整个调用过程是这样完成的:由于使用的是C调用规范,故后面的参数先入栈,则实参num2nd的值将会传递给形参b;而实参num1st的值将会传递给形参a;所以当调用choose函数时,相当于执行了choose(num1st, num2nd),故结果将返回 the 2nd one。

通过程序执行的结果,来证明我们的分析是正确的。

四、ELF文件

下面只是根据书上的内容,来简单的介绍一下数据结构,等以后对ELF进行深入研究之后,会专门写一篇关于ELF文件的介绍。

1、ELF文件格式:


由图中可以看出, ELF文件由4部分组成: ELF头(ELF header)、程序头表(Program header table)、节(Sections)和节头表(Section header table)。

2、ELF header的格式:

#define EI_NIDENT 16
typedef struct{
unsigned char               e_ident[EI_NIDENT];
Elf32_Half                     e_type;              //标识该文件的类型
Elf32_Half                     e_machine;       //表明运行该程序需要的体系结构
Elf32_Word                  e_version;         //确定文件的版本
Elf32_Addr                   e_entry;             //程序的入口地址
Elf32_Off                       e_phoff;            //Program header table在文件中的偏移量
Elf32_Off                       e_shoff;            //Section header table 在文件中的偏移量
Elf32_Word                   e_flags;           //对IA32而言,此项为0
Elf32_Half                      e_ehsize;         //ELF header的大小
Elf32_Half                      e_phentsize;   //Program header table中每一个条目的大小
Elf32_Half                      e_phnum;         //Program header table中有多少个条目
Elf32_Half                      e_shentsize;   //Section header table 中每一个条目的大小
Elf32_Half                      e_shnum;         //Section header table中有多少个条目
Elf32_Half                      e_shstrndx;
}Elf32_Ehdr;

3、Program header数据结构:

typedef struct {

Elf32_Wordp_type;//当前Program header所描述的段的类型

Elf32_Offp_offset;//段的第一个字节在文件中的偏移

Elf32_Addrp_vaddr;//段的第一个字节在内存中的虚拟地址

Elf32_Addrp_paddr;//在物理地址定位相关的系统中,此项是为物理地址保留

Elf32_Wordp_filesz;//段在文件中的长度

Elf32_Wordp_memsz;//段在内存中的长度

Elf32_Wordp_flags;//与段相关的标识

Elf32_Wordp_align;//根据此项值来确定段在文件中以及内存中如何对齐

}

五、Loader.bin进行加载内核——进入保护模式——向内核交出控制权

在面对一些复杂的程序时,我习惯做出一个简单的流程图,就是将整个程序过程一点点的走一遍,以便熟悉整个流程。下面就是我自己脑子里边想边绘出来的流程图,虽然简单,不规范,但是思路还是清晰得。

1、Loader加载内核


2、Loader进入保护模式


3、向内核交出控制权


就这样。我们从无到有,一点点的完成了Loader的所有工作。

4、下面就是最终的内存分配图

全面剖析《自己动手写操作系统》第五章--加载内核Kernel.bin

1、Linux系统的安装 和 与宿主计算机共享文件夹 2、global 和 extern 关键字的作用 3、C调用规范(C Calling Convention) 4、ELF文件 5、Load...
  • zgh1988
  • zgh1988
  • 2012年03月07日 22:04
  • 3306

Linux 可加载内核模块剖析

  • 2011年04月24日 08:45
  • 277KB
  • 下载

Linux如何在系统启动时自动加载内核模块

为搞清楚如何在系统启动时自动加载模块,搜索了好久,网上有很多人提出这个问题,但都没有正确的答案,无论是中文社区还是英文社区,大家的回答都没有讲到点子上,无非是围绕modprobe.conf、modpr...

Linux下通过加载内核计算CPU利用率以及内存利用率

大体上的思想就是通过 proc 文件查询,利用一个文件指针指到proc/stat,目录然后就可以查询相应的数据。 Linux 内核提供了一种通过 /proc 文件系统,在运行时访问内核内部数据结构、...

Linux可加载内核模块(LKM)

LKM(linux kernel module)
  • Fybon
  • Fybon
  • 2017年04月21日 17:29
  • 484

linux内核设计的艺术--加载内核代码

在BIOS触发0x19中断将磁盘的第一个扇区(512B)加载到内存中后,计算机才真正开始执行磁盘上的程序。而这512B的程序bootsect.s中的第一批代码,此时处理器还处于实模式内存寻址的最大范围...

Linux动态加载内核模块

Linux属于单内核,为了弥补单内核扩展性与维护性差的缺点,Linux引入动态可加载内核模块,模块可以在系统运行期间加载到内核或从内核卸载。模块是具有独立功能的程序,它可以被单独编译,但不能独立运行。...

加载内核模块,实现新的系统调用:遍历系统当前所有进程的任务描述符,并将pid组织成树状结构显示

在Linux内核中增加一个系统调用,并编写对应的linux应用程序。利用该系统调用能够遍历系统当前所有进程的任务描述符,并按进程父子关系将这些描述符所对应的进程id(PID)组织成树形结构显示。...

uboot中利用TFTP和NFS加载内核镜像和根文件系统

origin: http://www.cnblogs.com/cjjnjust/articles/1754849.html 主机说明: 主机guest 为虚拟机redhat9: I...

64位Ubuntu14.04系统下加载内核模块hello world

64位Ubuntu14.04系统下加载内核模块hello world
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:第五章--加载内核Kernel.bin
举报原因:
原因补充:

(最多只允许输入30个字)