通过简单的例子来理解LINUX中的加载器的概念?

时间:2013-09-17 05:45:09

标签: embedded-linux bootloader bootstrapping

据我所知,启动加载程序的核心是加载程序。通过加载器,我的意思是将加载另一个程序的程序。或者更具体地说,首先它将加载自身然后加载高级图像 - 例如内核。我没有制作一个引导程序,而是想通过运行一个可以加载另一个程序的操作系统来清除我对加载程序的怀疑。我明白每个流程图都完全独立于另一个流程图。所以,我要做的是制作一个简单的程序hello_world.c这将打印出伟大的“你好世界”。现在,我想制作一个加载程序来加载这个程序hello world。据我所知,症结分为两步

  1. 将hello world程序加载到RAM - 加载程序地址。
  2. JMP到入境地址。
  3. 因为,这是为了理解这个概念,我使用现成的实用程序readelf来读取hello world二进制文件的地址。这里的目的不是制作ELF解析器。 由于所有过程都是独立的并且使用虚拟内存。这将失败,如果我使用虚拟内存地址。现在,我被困在这里,我怎么能实现这个目标?

    #include "stdio.h"
       #include <sys/mman.h>
    
        int main( int argc, char **argv)
        {
          char *mem_ptr;
          FILE *fp;
    
          char *val;
          char *exec;
    
          mem_ptr = (char*) malloc(10*1024);
          fp = fopen("./hello_world.out","rb");
    
          fread(mem_ptr, 10240, 1, fp);
    
          //val = mem_ptr + 0x8048300;
    
          printf("The mem_ptr is %p\r\n",mem_ptr);
    
    
        exec = mmap(NULL, 10240, PROT_READ | PROT_WRITE | PROT_EXEC,
                          MAP_PRIVATE | MAP_ANONYMOUS, 0x9c65008, 0);
    
    
          memcpy(mem_ptr,exec,10240);
    
    
         __asm__("jmp 0x9c65008");
    
         fclose(fp);
    
    
          return 0;
        }
    

1 个答案:

答案 0 :(得分:1)

我的代表不足以让我添加评论。

正如Chris Stratton所说,你的问题听起来含糊不清(仍在编辑之后!)。你想

吗?
  1. 写一个bootloader,它会加载“Hello,World”而不是真正的OS? <--Actual Problem is saying this OR

  2. 编写一个将在OS上运行的程序(因此会有完整的操作系统),并使用该程序加载另一个可执行文件?<--Comments are saying this

  3. 答案会因此而有很大不同。

    在第一种情况下,BIOS上会出现bootloader,它会将一些预定义的内存块提取到RAM。所以你需要做的就是把Hello, World放在这个地方。关于这一点有很多事情,例如链加载和所有,但不确定这是否是你想要实现的。如果这不是您想要的,为什么使用bootstrap标签?

    在第二种情况下,fork() + exec()将为您完成。但请确保这样,将有两个不同的地址空间。如果你想让他们在同一个地址空间,我怀疑daily used OS(for normal guys)。你的大部分听起来都像是你想要做的。

    如果你想问一些与此不同的东西,请编辑几乎整个问题并仅询问那部分。(避免告诉你为什么要做某事,你认为你已经理解的等等)