- 博客(28)
- 资源 (14)
- 收藏
- 关注
原创 启动x86虚拟机
4.2.3 启动x86虚拟机<br />看到arch/x86/kernel/head_32.S的681行:<br />681 #include "../../x86/xen/xen-head.S"<br /> <br />这时候执行arch/x86/xen/xen-head.S下的代码:<br /> <br /> 19#ifdef CONFIG_X86_32<br /> 20 mov %esi,xen_start_info<br /> 21 mov $init_thread
2010-12-31 22:47:00
2770
原创 第三次启动保护模式
4.2.2 初始化GDT那么,这个gdt是在哪里初始化的呢,请看arch/x86/kernel/cpu/ common.c文件:86DEFINE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page) = { .gdt = {87#ifdef CONFIG_X86_6488 /*89 * We need valid kernel segments for data and code in long mode too90 * IR
2010-12-31 22:44:00
3067
原创 加载全局/中断描述符表
4.2 向start_kernel进发<br />分段、分页单元完成以后,我们的0号进程的运行环境就初步搭建起来了,那么就要“走向现代”,去调用start_kernel了,调用它之前还有几个重要的步骤要走。<br /> 4.2.1 加载全局/中断描述符表<br />很多人就有疑问,刚才我们设置好了中断描述符表,那内核怎么用它呢?不好意思,刚才在略过了的checkCPUtype过程中有一步非常重要的步骤,现在把它补上:<br />418 is386: movl $2,%ecx # se
2010-12-31 22:38:00
2587
原创 初始化中断描述符表
4.2.5 初始化中断描述符表<br />在完成了最重要和最核心的分段、分页环境的初始化后,还有一个就是初始化中断描述符idt的工作。<br /> <br /> 341/*<br /> 342 * Initialize eflags. Some BIOS's leave bits like NT set. This would<br /> 343 * confuse the debugger if this code is traced.<br /> 344 * XXX - best to initia
2010-12-31 22:36:00
2634
原创 第一次启动分页管理
4.2.4初始化分页环境从227行开始,著名的分页机制就粉墨登场了:227page_pde_offset = (__PAGE_OFFSET >> 20); 228 229 movl $pa(__brk_base), %edi 230 movl $pa(swapper_pg_dir), %edx 231 movl $PTE_IDENT_ATTR, %eax 23210: 233 leal PDE_IDENT_ATTR(%edi),%ecx
2010-12-31 22:33:00
3304
3
原创 第二次启动保护模式
4.2.3解压缩后的内核代码我们在链接vmlinux一节中看到,定义phys_startup_32为程序入口点,这个入口点才是解压缩后内核的真正开始的地方,而在链接脚本中,phys_startup_32是逻辑地址startup_32的物理地址。从进入保护模式那一刻起,程序就是用逻辑地址了,不过在启动分页机制之前,逻辑地址向物理地址的转换很简单,仅仅是va和pa操作,即物理地址转成逻辑地址和逻辑地址转成物理地址。第二个startup_32在arch/x86/kernel/head_32.S的85行,我们就开始
2010-12-31 22:28:00
3362
原创 解压缩内核
4.2.2解压缩内核解压缩内核使用的是decompress_kernel函数,来自arch/x86/boot/compressed/misc.c:301asmlinkage void decompress_kernel(void *rmode, memptr heap, 302 unsigned char *input_data, 303 unsigned long input
2010-12-31 22:24:00
3050
1
原创 32位x86保护模式代码
4 保护模式下的内核代码4.1 32位x86保护模式代码到保护模式的代码了,最先执行的代码就是arch/x86/boot/compressed/head_32.S中的startup_32,对于bzImage,grub把它加载到0x100000的位置。首先,来到34行ENTRY(startup_32),在这里,第一条保护模式的指令开始了。注意,前面的set_gdt仅仅是为了进入保护模式后的ljmp,意义并不大。 34ENTRY(startup_32) 35 cld 36 /*
2010-12-31 22:18:00
3420
1
原创 第一次启动保护模式
3.4.3安装临时全局描述符表回到go_to_protected_mode()函数中,接下来116和119行的两个函数比较简单,我们快速过一下: 35/* 36 * Disable all interrupts at the legacy PIC. 37 */ 38static void mask_all_interrupts(void) 39{ 40 outb(0xff, 0xa1); /* Mask all interrupts on the secondary P
2010-12-31 22:11:00
4245
6
原创 打开A20地址线
3.4.2打开A20地址线<br />回到go_to_protected_mode()的110行,调用一个enable_a20()函数。这里又用到“PC汇编及BIOS编程”的知识了。PC及其兼容机的第21根地址线(A20)较特殊,这就是“Intel 80286工作模式”提到的PC中安排的一个“门”控制该地址线是否有效。到了80286,系统的地址总线有原来的20根发展为24根,这样能够访问的内存可以达到2^24=16M。Intel在设计80286时提出的目标是向下兼容。所以,在实模式下,系统所表现的行为应该和
2010-12-31 22:09:00
8198
1
原创 实模式代码go_to_proteced_mode函数
3.4 实模式代码go_to_proteced_mode函数<br />main函数走到go_to_protected_mode,就是将告别实模式环境,进入保护模式了。保护模式(Protected Mode,或有时简写为 pmode)是一种 80286 系列和之后的 x86 兼容 CPU 操作模式。保护模式有一些新的特色,设计用来增强多功能和系统稳定度,像是内存保护,分页系统,以及硬件支援的虚拟内存。大部分的现今x86操作系统都在保护模式下运行,包含Linux、FreeBSD、以及微软 Windows 2.
2010-12-31 22:03:00
3150
1
原创 设置视频(Video)模式
<br />接下来main将执行进入保护模式前最重要的一个步骤,设置视频模式,调用set_video()函数,来自linux/arch/x86/boot/video.c:<br /> <br />315void set_video(void)<br /> 316{<br /> 317 u16 mode = boot_params.hdr.vid_mode;<br /> 318<br /> 319 RESET_HEAP();<br /> 320<br /> 321 s
2010-12-31 21:45:00
5443
原创 设置键盘属性
3.3.6设置键盘属性<br />所以回到main函数中,继续走,下一个该执行keyboard_set_repeat()函数了。<br /> <br /> 59/*<br /> 60 * Set the keyboard repeat rate to maximum. Unclear why this<br /> 61 * is done here; this might be possible to kill off as stale code.<br /> 62 */<br /> 63sta
2010-12-31 21:40:00
2693
原创 内存的检测
3.3.5内存的检测<br />好啦,回到main函数继续我们的旅程,147行detect_memory(),用于探测物理内存的布局。注意哈,这里是第一次出现与内存管理相关的代码。<br /> <br />122int detect_memory(void)<br /> 123{<br /> 124 int err = -1;<br /> 125<br /> 126 if (detect_memory_e820() > 0)<br /> 127 er
2010-12-31 21:32:00
2390
原创 设置BIOS的x86模式
3.3.4设置BIOS的x86模式<br />继续走,下一个函数,set_bios_mode(),跟main来自同一个文件:<br /> <br /> 94/*<br /> 95 * Tell the BIOS what CPU mode we intend to run in.<br /> 96 */<br /> 97static void set_bios_mode(void)<br /> 98{<br /> 99#ifdef CONFIG_I386<br /> 100 str
2010-12-31 21:24:00
2996
原创 初始化堆
3.3.2初始化堆<br />回到main函数,第二个函数,init_heap(),用来检查内核初始化阶段使用的堆:<br /> <br />109static void init_heap(void)<br /> 110{<br /> 111 char *stack_end;<br /> 112<br /> 113 if (boot_params.hdr.loadflags & CAN_USE_HEAP) {<br /> 114 asm("leal
2010-12-31 21:19:00
3466
原创 复制初始化头变量
3.3.1复制初始化头变量<br />131行是第一个函数,copy_boot_params(),顾名思义用来拷贝启动参数到内存的0号页面中:<br /> <br /> 29static void copy_boot_params(void)<br /> 30{<br /> 31 struct old_cmdline {<br /> 32 u16 cl_magic;<br /> 33 u16 cl_offset;<br />
2010-12-31 21:16:00
3566
原创 实模式代码main函数
3.3 实模式代码main函数<br />前面header.S中最后跳到main函数,在boot/main.c,void main()。再次强调一下,这一段C代码还是系统处于实模式下所执行的代码:<br /> <br />128void main(void)<br /> 129{<br /> 130 /* First, copy the boot header into the "zeropage" */<br /> 131 copy_boot_params();<br /> 1
2010-12-31 21:14:00
2632
4
原创 实模式汇编代码header.S——准备实模式下C语言环境
3.2.3准备实模式下C语言环境<br />好了,执行到setup代码了,header.S几乎所有的代码都在准备实模式下的C语言环境。在讲解这部分代码之前先回顾一下C语言程序关于程序中.text,.data,.bss等段的说明。由于历史原因,C程序一直由下列几部分组成:<br /> <br />1、正文段。这是由CPU执行的机器指令部分。通常,正文段是可共享的,所以即使是经常执行的程序(如文本编辑程序、C编译程序、shell等)在存储器中也只需有一个副本,另外,正文段常常是只读的,以防止程序由于意外事故而修
2010-12-31 21:06:00
4006
原创 实模式汇编代码header.S——头变量hdr
3.2.2初始化头变量hdr<br />在讲解“中世纪时代”的代码之前,先详细介绍一个在初始化当中非常重要的内容,hdr,全称叫做“setup_header”。这个头变量存放着所有初始化期间使用到的数据,在编译setup.bin的时候存放在.header段中,其代码我们看,从arch/x86/boot/header.S的第96行开始:<br /> <br /> 94 .section ".header", "a"<br /> 95 .globl hdr<br /> 96h
2010-12-31 21:02:00
3307
原创 实模式汇编代码header.S——无用的bootsect
3.2 实模式汇编代码header.S<br />如上所述,第一和第二部分是实模式代码,这些代码来自于汇编程序arch/x86/boot/header.S和c程序arch/x86/boot/main.c。<br /> <br />再从加载开始说,如上所述,vmlinuz保护模式的代码加载到0x100000开始的位置。而实模式的代码,因为被加载的位置不要求是固定的,也就是上面文档中看到的:<br /> Kernel setup | T
2010-12-31 20:59:00
3492
原创 内核映像内存布局
3 实模式下的内核代码<br />通过上一章节,大家都看到了,最终每个Linux系统都有一个类似/boot/vmlinuz-2.6.x的文件,就是所谓的内核映像。而大家对从源代码到内核映像的形成有了一个较完整的认识。前面也提到了,系统启动的时候,grub会把内核映像加载到内存,然后执行它。总结一下Grub的这一个过程,就是:<br />1. 调用一个BIOS过程显示“Loading”信息。<br />2. 调用一个BIOS过程从磁盘装入内核映像的初始部分,即将内核映像的第一个512字
2010-12-31 20:55:00
4278
原创 内核映像的形成——制作bzImage
2.2.6制作bzImage<br />回到顶层Makefile的849行,随着vmlinux的链接工作结束,在主目录下生成了vmlinux文件,vmlinux目标也就结束了。那么就会来到arch/x86/Makefile的155行bzImage目标。看到这个目标,就知道后面的工作就算打包压缩vmlinux并制作bzImage了。看到156行,因为CONFIG_X86_DECODER_SELFTEST没有设置,所以会直接执行159行以后的命令:<br />159 $(Q)$(MAKE) $(b
2010-12-29 22:54:00
7296
1
原创 内核映像的形成——链接vmlinux
2.2.5链接vmlinux<br />当我们前面$(vmlinux-dirs)目标的工作做完后,也就是形成了各目录中的built-in.o文件,那么就会回到$(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds)所对应的目标中,这个目标是一行空命令,看到699行:<br />699 vmlinux-init := $(head-y) $(init-y)<br />700 vmlinux-main := $(core-y) $(libs-y) $(driv
2010-12-29 22:44:00
6386
原创 内核映像的形成——递归编译各对象
2.2.4递归编译各对象<br />当prepare和scripts目标执行完后,就会去执行$(vmlinux-dirs)目标的命令:<br />883 $(vmlinux-dirs): prepare scripts<br />884 $(Q)$(MAKE) $(build)=$@<br />885 ifdef CONFIG_MODULES<br />886 $(Q)$(MAKE) $(modbuiltin)=$@<br />887 endif<br /> <br />别看这小
2010-12-29 22:40:00
5153
1
原创 内核映像的形成——prepare和scripts目标
2.2.3 prepare和scripts目标<br />上一节我们找到了整个KBuild体系的第一个目标,根据是否进行了编译配置而分别是385行的scripts_basic和949行的include/config/kernel.release。更重要的是,通过第一个目标的寻找,我们把KBuild体系的整个顶层Makefile文件脉络梳理了一遍,这对我们研究vmlinux的形成及其重要。下面我们就从第一个目标开始,对编译配置后make的整个过程来过一遍。<br /> <br />949行,第一个目标:<br
2010-12-29 22:37:00
5830
1
原创 内核映像的形成——寻找第一个目标
2.2.2寻找第一个目标<br />在make menucofig之后,即编译内核的第二步,是执行make命令(2.6之前的内核是执行make bzImage)。我们知道,make命令没有任何参数的时候,默认去执行当前目录下的Makefile文件。我们编译内核的时候是在刚刚从kernel.org下载来的linux-2.6.34.1源码包,所以执行的就是linux-2.6.34.1/Makefile文件,而这个文件的突破口,是找到它的第一个目标。下面,我们就来详细分析这个文件。<br /> <br />首先是
2010-12-29 22:33:00
4125
2
原创 内核映像的形成——编译配置
2.2 内核编译分析<br />关于Kbuild的预备知识先说到这里,有了上面的这些知识大家就可以上手了,其他的那些重要的知识主要涉及到一些细节,等我们遇到了再去查GNU Make手册和linux-2.6.34.1/Documentation/kbuild下的那些文档(注意,这是一种很重要的学习方法)。<br /> <br />在递归访问目录之前,顶层Makefile要完成设置环境变量以及递归访问的准备工作。顶层Makefile包含的公共部分,而 arch/$(ARCH)/Makefile 包含着针对某一特
2010-12-29 22:28:00
4414
1
NFS文件系统
2012-04-08
数据结构与算法——面向对象C++设计模式
2011-11-27
高性能分布式监控系统Ganglia详解
2011-07-10
疯狂内核之——内核初始化
2011-05-30
疯狂内核之——Linux虚拟内存
2011-05-30
疯狂内核之——进程管理子系统
2011-05-30
疯狂内核之——Linux预备知识.pdf
2011-05-30
基于C++语言的GoF23种设计模式
2011-05-29
从8086到Pentium Ⅲ微型计算机及接口技术3
2010-09-24
Linux sysfs 文件系统机制详解
2009-12-14
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人