当前位置: 首页 > news >正文

站长统计 站长统计wordpress安全检测工具

站长统计 站长统计,wordpress安全检测工具,超级采购小程序怎么注册,服装网站建设运营规划三、Boot Loader 的主要任务与典型结构框架 在继续本节的讨论之前#xff0c;首先我们做一个假定#xff0c;那就是#xff1a;假定内核映像与根文件系统映像都被加载到 RAM 中运行。之所以提出这样一个假设前提是因为#xff0c;在嵌入式系统中内核映像与根文件系统映像也…三、Boot Loader 的主要任务与典型结构框架 在继续本节的讨论之前首先我们做一个假定那就是假定内核映像与根文件系统映像都被加载到 RAM 中运行。之所以提出这样一个假设前提是因为在嵌入式系统中内核映像与根文件系统映像也可以直接在 ROM 或 Flash 这样的固态存储设备中直接运行。但这种做法无疑是以运行速度的牺牲为代价的。从操作系统的角度看Boot Loader 的总目标就是正确地调用内核来执行。 另外由于 Boot Loader 的实现依赖于 CPU 的体系结构因此大多数 Boot Loader 都分为 stage1 和 stage2 两大部分。依赖于 CPU 体系结构的代码比如设备初始化代码等通常都放在 stage1 中而且通常都用汇编语言来实现以达到短小精悍的目的。而 stage2 则通常用C语言来实现这样可以实现给复杂的功能而且代码会具有更好的可读性和可移植性。 Boot Loader 的 stage1 通常包括以下步骤(以执行的先后顺序)·硬件设备初始化。·为加载 Boot Loader 的 stage2 准备 RAM 空间。·拷贝 Boot Loader 的 stage2 到 RAM 空间中。·设置好堆栈。·跳转到 stage2 的 C 入口点。Boot Loader 的 stage2 通常包括以下步骤(以执行的先后顺序)·初始化本阶段要使用到的硬件设备。·检测系统内存映射(memory map)。·将 kernel 映像和根文件系统映像从 flash 上读到 RAM 空间中。·为内核设置启动参数。·调用内核。 3.1 Boot Loader 的 stage1 3.1.1 基本的硬件初始化 这是 Boot Loader 一开始就执行的操作其目的是为 stage2 的执行以及随后的 kernel的执行准备好一些基本的硬件环境。它通常包括以下步骤以执行的先后顺序 1屏蔽所有的中断。为中断提供服务通常是 OS 设备驱动程序的责任因此在 Boot Loader 的执行全过程中可以不必响应任何中断。中断屏蔽可以通过写 CPU 的中断屏蔽寄存器或状态寄存器比如 ARM 的 CPSR 寄存器来完成。 2设置 CPU 的速度和时钟频率。 3RAM 初始化。包括正确地设置系统的内存控制器的功能寄存器以及各内存库控制寄存器等。 4初始化 LED。典型地通过 GPIO 来驱动 LED其目的是表明系统的状态是 OK 还是 Error。如果板子上没有 LED那么也可以通过初始化 UART 向串口打印 Boot Loader 的Logo 字符信息来完成这一点。 5 关闭 CPU 内部指令数据 cache。 3.1.2 为加载 stage2 准备 RAM 空间 为了获得更快的执行速度通常把 stage2 加载到 RAM 空间中来执行因此必须为加载 Boot Loader 的 stage2 准备好一段可用的 RAM 空间范围。 由于 stage2 通常是 C 语言执行代码因此在考虑空间大小时除了 stage2 可执行映象的大小外还必须把堆栈空间也考虑进来。此外空间大小最好是 memory page 大小(通常是 4KB)的倍数。一般而言1M 的 RAM 空间已经足够了。具体的地址范围可以任意安排比如 blob 就将它的 stage2 可执行映像安排到从系统 RAM 起始地址 0xc0200000 开始的 1M 空间内执行。但是将 stage2 安排到整个 RAM 空间的最顶 1MB(也即(RamEnd-1MB) - RamEnd)是一种值得推荐的方法。 为了后面的叙述方便这里把所安排的 RAM 空间范围的大小记为stage2_size(字节)把起始地址和终止地址分别记为stage2_start 和 stage2_end(这两个地址均以 4 字节边界对齐)。因此 stage2_endstage2_startstage2_size另外还必须确保所安排的地址范围的的确确是可读写的 RAM 空间因此必须对你所安排的地址范围进行测试。具体的测试方法可以采用类似于 blob 的方法也即以 memory page 为被测试单位测试每个 memory page 开始的两个字是否是可读写的。为了后面叙述的方便我们记这个检测算法为test_mempage其具体步骤如下 1先保存 memory page 一开始两个字的内容。 2向这两个字中写入任意的数字。比如向第一个字写入 0x55第 2 个字写入 0xaa。3然后立即将这两个字的内容读回。显然我们读到的内容应该分别是 0x55 和 0xaa。如果不是则说明这个 memory page 所占据的地址范围不是一段有效的 RAM 空间。 4再向这两个字中写入任意的数字。比如向第一个字写入 0xaa第 2 个字中写入 0x55。 5然后立即将这两个字的内容立即读回。显然我们读到的内容应该分别是 0xaa 和 0x55。如果不是则说明这个 memory page 所占据的地址范围不是一段有效的 RAM 空间。 6恢复这两个字的原始内容。测试完毕。 为了得到一段干净的 RAM 空间范围我们也可以将所安排的 RAM 空间范围进行清零操作。 3.1.3 拷贝 stage2 到 RAM 中 拷贝时要确定两点(1) stage2 的可执行映象在固态存储设备的存放起始地址和终止地址(2) RAM 空间的起始地址。 3.1.4 设置堆栈指针 sp 堆栈指针的设置是为了执行 C 语言代码作好准备。通常我们可以把 sp 的值设置为(stage2_end-4)也即在 3.1.2 节所安排的那个 1MB 的 RAM 空间的最顶端(堆栈向下生长)。此外在设置堆栈指针 sp 之前也可以关闭 led 灯以提示用户我们准备跳转到 stage2。经过上述这些执行步骤后系统的物理内存布局应该如下图2所示。 3.1.5 跳转到 stage2 的 C 入口点 在上述一切都就绪后就可以跳转到 Boot Loader 的 stage2 去执行了。比如在 ARM 系统中这可以通过修改 PC 寄存器为合适的地址来实现。 http://tech.ccidnet.com/pub/attachme.../12/268047.gif图2 bootloader 的 stage2 可执行映象刚被拷贝到 RAM 空间时的系统内存布局3.2 Boot Loader 的 stage2 正如前面所说stage2 的代码通常用 C 语言来实现以便于实现更复杂的功能和取得更好的代码可读性和可移植性。但是与普通 C 语言应用程序不同的是在编译和链接 bootloader 这样的程序时我们不能使用 glibc 库中的任何支持函数。其原因是显而易见的。这就给我们带来一个问题那就是从那里跳转进 main() 函数呢直接把 main() 函数的起始地址作为整个 stage2 执行映像的入口点或许是最直接的想法。但是这样做有两个缺点1)无法通过main() 函数传递函数参数2)无法处理 main() 函数返回的情况。一种更为巧妙的方法是利用 trampoline(*簧床)的概念。也即用汇编语言写一段trampoline 小程序并将这段 trampoline 小程序来作为 stage2 可执行映象的执行入口点。然后我们可以在 trampoline 汇编小程序中用 CPU 跳转指令跳入 main() 函数中去执行而当main() 函数返回时CPU 执行路径显然再次回到我们的 trampoline 程序。简而言之这种方法的思想就是用这段 trampoline 小程序来作为 main() 函数的外部包裹(external wrapper)。 下面给出一个简单的 trampoline 程序示例(来自blob) .text.globl _trampoline_trampoline:bl main/* if main ever returns we just call it again */b _trampoline可以看出当 main() 函数返回后我们又用一条跳转指令重新执行 trampoline 程序――当然也就重新执行 main() 函数这也就是 trampoline(*簧床)一词的意思所在。 3.2.1初始化本阶段要使用到的硬件设备 这通常包括1初始化至少一个串口以便和终端用户进行 I/O 输出信息2初始化计时器等。在初始化这些设备之前也可以重新把 LED 灯点亮以表明我们已经进入 main() 函数执行。 设备初始化完成后可以输出一些打印信息程序名字字符串、版本号等。 3.2.2 检测系统的内存映射memory map 所谓内存映射就是指在整个 4GB 物理地址空间中有哪些地址范围被分配用来寻址系统的 RAM 单元。比如在 SA-1100 CPU 中从 0xC000,0000 开始的 512M 地址空间被用作系统的 RAM 地址空间而在 Samsung S3C44B0X CPU 中从 0x0c00,0000 到 0x1000,0000之间的 64M 地址空间被用作系统的 RAM 地址空间。虽然 CPU 通常预留出一大段足够的地址空间给系统 RAM但是在搭建具体的嵌入式系统时却不一定会实现 CPU 预留的全部 RAM 地址空间。也就是说具体的嵌入式系统往往只把 CPU 预留的全部 RAM 地址空间中的一部分映射到 RAM 单元上而让剩下的那部分预留 RAM 地址空间处于未使用状态。由于上述这个事实因此 Boot Loader 的 stage2 必须在它想干点什么 (比如将存储在 flash 上的内核映像读到 RAM 空间中) 之前检测整个系统的内存映射情况也即它必须知道 CPU 预留的全部 RAM 地址空间中的哪些被真正映射到 RAM 地址单元哪些是处于 unused 状态的。 (1) 内存映射的描述 可以用如下数据结构来描述 RAM 地址空间中的一段连续(continuous)的地址范围 typedef struct memory_area_struct {u32 start; /* the base address of the memory region */u32 size; /* the byte number of the memory region */int used;} memory_area_t;这段 RAM 地址空间中的连续地址范围可以处于两种状态之一(1)used1则说明这段连续的地址范围已被实现也即真正地被映射到 RAM 单元上。(2)used0则说明这段连续的地址范围并未被系统所实现而是处于未使用状态。 基于上述 memory_area_t 数据结构整个 CPU 预留的 RAM 地址空间可以用一个 memory_area_t 类型的数组来表示如下所示 memory_area_t memory_map[NUM_MEM_AREAS] {[0 ... (NUM_MEM_AREAS - 1)] {.start 0,.size 0,.used 0},};(2) 内存映射的检测 下面我们给出一个可用来检测整个 RAM 地址空间内存映射情况的简单而有效的算法 /* 数组初始化 */for(i 0; i NUM_MEM_AREAS; i)memory_map[i].used 0;/* first write a 0 to all memory locations */for(addr MEM_START; addr MEM_END; addr PAGE_SIZE)* (u32 *)addr 0;for(i 0, addr MEM_START; addr MEM_END; addr PAGE_SIZE) {/** 检测从基地址 MEM_STARTi*PAGE_SIZE 开始,大小为* PAGE_SIZE 的地址空间是否是有效的RAM地址空间。*/调用3.1.2节中的算法test_mempage()if ( current memory page isnot a valid ram page) {/* no RAM here */if(memory_map[i].used )i;continue;}/** 当前页已经是一个被映射到 RAM 的有效地址范围* 但是还要看看当前页是否只是 4GB 地址空间中某个地址页的别名*/if(* (u32 *)addr ! 0) { /* alias? *//* 这个内存页是 4GB 地址空间中某个地址页的别名 */if ( memory_map[i].used )i;continue;}/** 当前页已经是一个被映射到 RAM 的有效地址范围* 而且它也不是 4GB 地址空间中某个地址页的别名。*/if (memory_map[i].used 0) {memory_map[i].start addr;memory_map[i].size PAGE_SIZE;memory_map[i].used 1;} else {memory_map[i].size PAGE_SIZE;}} /* end of for (…) */在用上述算法检测完系统的内存映射情况后Boot Loader 也可以将内存映射的详细信息打印到串口。 3.2.3 加载内核映像和根文件系统映像 (1) 规划内存占用的布局 这里包括两个方面(1)内核映像所占用的内存范围2根文件系统所占用的内存范围。在规划内存占用的布局时主要考虑基地址和映像的大小两个方面。 对于内核映像一般将其拷贝到从(MEM_START0x8000) 这个基地址开始的大约1MB大小的内存范围内(嵌入式 Linux 的内核一般都不操过 1MB)。为什么要把从 MEM_START 到 MEM_START0x8000 这段 32KB 大小的内存空出来呢这是因为 Linux 内核要在这段内存中放置一些全局数据结构如启动参数和内核页表等信息。 而对于根文件系统映像则一般将其拷贝到 MEM_START0x0010,0000 开始的地方。如果用Ramdisk 作为根文件系统映像则其解压后的大小一般是1MB。 2从 Flash 上拷贝 由于像 ARM 这样的嵌入式 CPU 通常都是在统一的内存地址空间中寻址 Flash 等固态存储设备的因此从 Flash 上读取数据与从 RAM 单元中读取数据并没有什么不同。用一个简单的循环就可以完成从 Flash 设备上拷贝映像的工作 while(count) {*dest *src; /* they are all aligned with word boundary */count - 4; /* byte number */};3.2.4 设置内核的启动参数 应该说在将内核映像和根文件系统映像拷贝到 RAM 空间中后就可以准备启动 Linux 内核了。但是在调用内核之前应该作一步准备工作即设置 Linux 内核的启动参数。Linux 2.4.x 以后的内核都期望以标记列表(tagged list)的形式来传递启动参数。启动参数标记列表以标记 ATAG_CORE 开始以标记 ATAG_NONE 结束。每个标记由标识被传递参数的 tag_header 结构以及随后的参数值数据结构来组成。数据结构 tag 和 tag_header定义在 Linux 内核源码的include/asm/setup.h 头文件中 /* The list ends with an ATAG_NONE node. */#define ATAG_NONE 0x00000000struct tag_header {u32 size; /* 注意这里size是字数为单位的 */u32 tag;};……struct tag {struct tag_header hdr;union {struct tag_core core;struct tag_mem32 mem;struct tag_videotext videotext;struct tag_ramdisk ramdisk;struct tag_initrd initrd;struct tag_serialnr serialnr;struct tag_revision revision;struct tag_videolfb videolfb;struct tag_cmdline cmdline;/** Acorn specific*/struct tag_acorn acorn;/** DC21285 specific*/struct tag_memclk memclk;} u;};在嵌入式 Linux 系统中通常需要由 Boot Loader 设置的常见启动参数有ATAG_CORE、ATAG_MEM、ATAG_CMDLINE、ATAG_RAMDISK、ATAG_INITRD等。比如设置 ATAG_CORE 的代码如下 params (struct tag *)BOOT_PARAMS;params-hdr.tag ATAG_CORE;params-hdr.size tag_size(tag_core);params-u.core.flags 0;params-u.core.pagesize 0;params-u.core.rootdev 0;params tag_next(params);其中BOOT_PARAMS 表示内核启动参数在内存中的起始基地址指针 params 是一个 struct tag 类型的指针。宏 tag_next() 将以指向当前标记的指针为参数计算紧临当前标记的下一个标记的起始地址。注意内核的根文件系统所在的设备ID就是在这里设置的。下面是设置内存映射情况的示例代码 for(i 0; i NUM_MEM_AREAS; i) {if(memory_map[i].used) {params-hdr.tag ATAG_MEM;params-hdr.size tag_size(tag_mem32);params-u.mem.start memory_map[i].start;params-u.mem.size memory_map[i].size;params tag_next(params);}}可以看出在 memory_map数组中每一个有效的内存段都对应一个 ATAG_MEM 参数标记。 Linux 内核在启动时可以以命令行参数的形式来接收信息利用这一点我们可以向内核提供那些内核不能自己检测的硬件参数信息或者重载(override)内核自己检测到的信息。比如我们用这样一个命令行参数字符串consolettyS0,115200n8来通知内核以 ttyS0作为控制台且串口采用 115200bps、无奇偶校验、8位数据位这样的设置。下面是一段设置调用内核命令行参数字符串的示例代码 char *p;/* eat leading white space */for(p commandline; *p ; p);/* skip non-existent command lines so the kernel will still* use its default command line.*/if(*p \0)return;params-hdr.tag ATAG_CMDLINE;params-hdr.size (sizeof(struct tag_header) strlen(p) 1 4) 2;strcpy(params-u.cmdline.cmdline, p);params tag_next(params);请注意在上述代码中设置 tag_header 的大小时必须包括字符串的终止符\0此外还要将字节数向上圆整4个字节因为 tag_header 结构中的size 成员表示的是字数。 下面是设置 ATAG_INITRD 的示例代码它告诉内核在 RAM 中的什么地方可以找到 initrd 映象(压缩格式)以及它的大小 params-hdr.tag ATAG_INITRD2;params-hdr.size tag_size(tag_initrd);params-u.initrd.start RAMDISK_RAM_BASE;params-u.initrd.size INITRD_LEN;params tag_next(params);下面是设置 ATAG_RAMDISK 的示例代码它告诉内核解压后的 Ramdisk 有多大单位是KB params-hdr.tag ATAG_RAMDISK;params-hdr.size tag_size(tag_ramdisk);params-u.ramdisk.start 0;params-u.ramdisk.size RAMDISK_SIZE; /* 请注意单位是KB */params-u.ramdisk.flags 1; /* automatically load ramdisk */params tag_next(params);最后设置 ATAG_NONE 标记结束整个启动参数列表 static void setup_end_tag(void){params-hdr.tag ATAG_NONE;params-hdr.size 0;}3.2.5 调用内核 Boot Loader 调用 Linux 内核的方法是直接跳转到内核的第一条指令处也即直接跳转到MEM_START0x8000 地址处。在跳转时下列条件要满足 1 CPU 寄存器的设置·R00R1机器类型 ID关于 Machine Type Number可以参见 linux/arch/arm/tools/mach-types。R2启动参数标记列表在 RAM 中起始基地址 2 CPU 模式·必须禁止中断IRQs和FIQs·CPU 必须 SVC 模式 3 Cache 和 MMU 的设置·MMU 必须关闭·指令 Cache 可以打开也可以关闭·数据 Cache 必须关闭 如果用 C 语言可以像下列示例代码这样来调用内核 void (*theKernel)(int zero, int arch, u32 params_addr) (void (*)(int, int, u32))KERNEL_RAM_BASE;……theKernel(0, ARCH_NUMBER, (u32) kernel_params_start);注意theKernel()函数调用应该永远不返回的。如果这个调用返回则说明出错。
http://www.yutouwan.com/news/106034/

相关文章:

  • 企业网站模板图片做铝锭的网站
  • 网站设计建设定制jquery 单击input输入框弹出选择框多用于人才类网站
  • 白沟网站建设做网站的素材和步骤
  • 网站开发公司杭州四川省建设网站
  • 重庆做商城网站设计wordpress教材
  • 江西南昌小程序开发seo入门讲解
  • 集团响应式网站建设网站建设哪家强
  • 北京网站设计公司cg成都柚米科技15开发软件的网站
  • 常州网站建设外包哈尔滨高端网站设计
  • 电商网站建专业团队海报
  • 做网页兼职网站有哪些通州北苑网站建设
  • 沧州网站建设 熊掌号中铁建设中南分公司
  • 美容行业网站建设中国商标网查询入口
  • 兰州网站关键词优化制作视频软件
  • 做网站 数据库政务信息系统网站建设规范
  • 网站建设 的销售图片东莞网站优化一般多少钱
  • 石家庄裕华区网站建设校园网站建设 必要性分析
  • 查建设公司年度保证金网站discuz论坛建站教程
  • 给公司做一个网站咸阳专业学校网站建设
  • 权重域名做网站有用么app小游戏开发公司
  • 网站开发 英文如何知道一个网站做的什么推广
  • asp.net网站开发书籍软件项目管理是做什么的
  • 精品网站建设价格wordpress绑定七牛
  • 莱州人社局网站建公司网站需要哪些资料
  • 网络app开发网站建设农家乐网站建设营销方案
  • 云主机建设网站广州seo建站
  • 外包公司 网站建设 深圳万州网站建设果园路
  • 巩义网站建设与制作郑州锐途网站建设
  • 哪里有网站模板下载中国文化网站建设方案
  • 环保空调东莞网站建设分析网站的外链