引导内核时.init节如何工作

时间:2019-01-11 04:43:49

标签: operating-system

我试图了解一个简单内核的启动过程。下面是一个链接器脚本,在其中创建一个.init.data节。

   **Here is the solution for you.**

   1.  **Connect with rabbitMQ using API**  

       public WebClient GetRabbitMqConnection(string userName, string password)
       {
            var client = new WebClient(); 
            client.Credentials = new NetworkCredential(userName, password);
            return client;
       }

   2. **Retrieve message by providing appropriate parameter in below method.**

      public string GetRabbitMQMessages(string domainName, string port, string 
                                        queueName, string virtualHost, WebClient 
                                        client, string methodType)
      {
                 string messageResult = string.Empty;
                 string strUri = "http://" + domainName + ":" + port + "/api/queues/" 
                                 + virtualHost + "/";
                 var data = client.DownloadString(strUri + queueName + "/");
                 var queueInfo = JsonConvert.DeserializeObject<QueueInfo>(data);
                 if (queueInfo == null || queueInfo.messages == 0)
                     return string.Empty;
                 if (methodType == "POST")
                 {
                     string postbody = "  
                 {\"ackmode\":\"ack_requeue_true\",\"count\":
                  \"$totalMessageCount\",
                  \"name\":\"${DomainName}\",\"requeue\":\"false\",
                  \"encoding\":\"auto\",\"vhost\" : \"${QueueName}\"}";
                  postbody = postbody.Replace("$totalMessageCount", 
                  queueInfo.messages.ToString()).Replace("${DomainName}", 
                  domainName).Replace("${QueueName}", queueName);
                  messageResult = client.UploadString(strUri + queueName + "/get", 
                  "POST", postbody);
                 }
                return messageResult;
        }

    **I wish it will solve your problem. All the best and cheers !!!!!!**

然后我在简单的kernel.c文件中创建ENTRY(_start) SECTIONS { . = 1M; .text BLOCK(4K) : ALIGN(4K) { *(.multiboot) *(.text) } .rodata BLOCK(4K) : ALIGN(4K) { *(.rodata) } .data BLOCK(4K) : ALIGN(4K) { *(.data) } .bss BLOCK(4K) : ALIGN(4K) { *(COMMON) *(.bss) } .init.data : { __initcall6_start = .; *(.initcall6.init) } } 。然后,我创建一个函数指针myFunc并将其放在__initcall_myFunc6部分中。我给它分配了对myFunc的引用。

.initcall6.init

当我使用qemu加载内核时,myFunc在内核main之前被调用。我希望什么都不会发生,因为没有任何东西调用myFunc。在尝试了解驱动程序的初始化时,我从Linux借来了其中的一些内容。

可以在github中获得该项目:https://github.com/wbranson/testOS

关于ELF文件的.init和.fini部分,有很多信息,但是所有这些都假定进程/程序将由内核加载。我正在尝试查找可以解释为什么/如何发生的信息。

1 个答案:

答案 0 :(得分:0)

如果您决定内核应有一个.init.data部分,那么您还应决定内核应如何使用其.init.data部分。

随机猜测;我假设您决定内核应该有一个.init.data部分,以使内核更容易丢弃初始化后将不再使用的内容(因此它可以释放RAM并将其用于更多有用的东西。)

我决定我的内核不应包含.init.data部分。这主要是因为它是一个微内核(开始时很少进行内核初始化),并且因为大多数初始化都移出了内核(进入了在启动后被丢弃的早期启动代码)。

  

当我使用qemu加载内核时,myFunc在内核main之前被调用。我希望什么都不会发生,因为没有任何东西调用myFunc。当我试图了解驱动程序的初始化时,我已经从Linux中借用了其中的一部分。

您告诉链接器将符号_start用作入口点;然后您为_start编写了call _init的代码。 _init代码不是完整功能。它是函数的开始,没有结束(没有return),这会导致链接器想要执行的随机垃圾。在您的情况下,“链接器感觉就像在扔垃圾”是您的myFunc()(因为它恰好位于同一部分)。

请注意,这是所有根本不应该存在于内核中的可怕的GCC黑客。

更具体地说,.init.fini混乱是针对托管环境的,这些环境中您需要花费大量的运行时间来担心;并且不应该用于独立的环境,例如内核,其中庞大的运行时(取决于不存在的内核API)毫无意义。