编写我自己的 init 可执行文件

2024-01-10

我想创建自己的 init 并为下雪的周末带来一些 Linux 乐趣。我知道,内核使用 rootfs 启动,并在加载驱动程序和安装磁盘后将流程提供给 /sbin/init 。我下载了ubuntu云镜像并尝试使用kvm直接启动内核,如下所示:

kvm -m 1G -nographic -kernel vmlinuz-3.19.0-32-generic -initrd initrd.img-3.19.0-32-generic -append "console=ttyS0 root=/dev/sda1 rw init=/myinit" -hda mydisk.img 

它与 trusty-server-cloudimg-amd64-disk1.img 配合得很好(如果您不介意挂在 cloud-init 上),然后我继续复制它并删除其内容。

modprobe nbd
qemu-nbd -c /dev/nbd0 mydisk.img 
fdisk -l /dev/nbd0 # confirm partition
mount /dev/nbd0p1 disk/
# Delete all files with myinit.c and myinit

这是我神奇的初始化:

int main(){
    printf("Welcome to my kernel\n");
    printf("Welcome to my kernel\n");
    printf("Welcome to my kernel\n");
    while(1);
}

我用它编译gcc -static myinit.c -o myinit。然而,由于我的 init,发生了内核恐慌。我通过将 myinit 重命名为 myinit2 来验证它,内核找不到它,并且它没有崩溃。我知道编写init不可能像上面那么简单,但是它需要哪些步骤呢?我正在阅读新贵源代码

Begin: Mounting root file system ... Begin: Running /scripts/local-top ... done.
Begin: Running /scripts/local-premount ... [    1.460164] tsc: Refined TSC clocksource calibration: 2394.558 MHz
[    1.866560] input: ImExPS/2 Generic Explorer Mouse as /devices/platform/i8042/serio1/input/input3
done.
[    6.251763] EXT4-fs (sda1): recovery complete
[    6.253623] EXT4-fs (sda1): mounted filesystem with ordered data mode. Opts: (null)
Begin: Running /scripts/local-bottom ... done.
done.
Begin: Running /scripts/init-bottom ... mount: mounting /dev on /root/dev failed: No such file or directory
done.
mount: mounting /sys on /root/sys failed: No such file or directory
mount: mounting /proc on /root/proc failed: No such file or directory
[    6.299404] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000200
[    6.299404] 
[    6.300013] CPU: 0 PID: 1 Comm: init Not tainted 3.19.0-32-generic #37~14.04.1-Ubuntu
[    6.300013] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
[    6.300013]  ffff88003c118700 ffff88003dee7e38 ffffffff817af41b 00000000000017d6
[    6.300013]  ffffffff81a90be8 ffff88003dee7eb8 ffffffff817a925b ffff88003dee8000
[    6.300013]  ffffffff00000010 ffff88003dee7ec8 ffff88003dee7e68 ffffffff81c5ee20
[    6.300013] Call Trace:
[    6.300013]  [<ffffffff817af41b>] dump_stack+0x45/0x57
[    6.300013]  [<ffffffff817a925b>] panic+0xc1/0x1f5
[    6.300013]  [<ffffffff81077b01>] do_exit+0xa11/0xb00
[    6.300013]  [<ffffffff811ec53c>] ? vfs_write+0x15c/0x1f0
[    6.300013]  [<ffffffff81077c7f>] do_group_exit+0x3f/0xa0
[    6.300013]  [<ffffffff81077cf4>] SyS_exit_group+0x14/0x20
[    6.300013]  [<ffffffff817b6dcd>] system_call_fastpath+0x16/0x1b
[    6.300013] Kernel Offset: 0x0 from 0xffffffff81000000 (relocation range: 0xffffffff80000000-0xffffffffbfffffff)
[    6.300013] drm_kms_helper: panic occurred, switching back to text console
[    6.300013] ---[ end Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000200
[    6.300013] 

我知道 myinit 是完全静态的:

# ldd disk/myinit
    not a dynamic executable

所以我想它不应该依赖于其他任何东西。但我做错了什么以及为什么内核会恐慌?(没有 printfs 内核也会发生恐慌)

我正在阅读 sysvinit 源代码(它应该比 upstart & systemd & openrc 更简单),但它太长了,但 init 的主要思想是拥有进程,它也位于 while(1) 循环中。


Your stdin, stdout and stderr当您的init开始。在开始时经常会看到类似于以下内容的序列init程序:

    int onefd = open("/dev/console", O_RDONLY, 0);
    dup2(onefd, 0); // stdin
    int twofd = open("/dev/console", O_RDWR, 0);
    dup2(twofd, 1); // stdout
    dup2(twofd, 2); // stderr

    if (onefd > 2) close(onefd);
    if (twofd > 2) close(twofd);

这确保了stdin, stdout and stderr连接到系统控制台。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

编写我自己的 init 可执行文件 的相关文章

  • GLKit的GLKMatrix“列专业”如何?

    前提A 当谈论线性存储器中的 列主 矩阵时 列被一个接一个地指定 使得存储器中的前 4 个条目对应于矩阵中的第一列 另一方面 行主 矩阵被理解为依次指定行 以便内存中的前 4 个条目指定矩阵的第一行 A GLKMatrix4看起来像这样 u
  • Web 客户端和 Expect100Continue

    使用 WebClient C NET 时设置 Expect100Continue 的最佳方法是什么 我有下面的代码 我仍然在标题中看到 100 continue 愚蠢的 apache 仍然抱怨 505 错误 string url http
  • 为什么两个不同的 Base64 字符串的转换会返回相等的字节数组?

    我想知道为什么从 base64 字符串转换会为不同的字符串返回相同的字节数组 const string s1 dg const string s2 dq byte a1 Convert FromBase64String s1 byte a2
  • 动态加载程序集的应用程序配置

    我正在尝试将模块动态加载到我的应用程序中 但我想为每个模块指定单独的 app config 文件 假设我的主应用程序有以下 app config 设置
  • 从Web API同步调用外部api

    我需要从我的 Web API 2 控制器调用外部 api 类似于此处的要求 使用 HttpClient 从 Web API 操作调用外部 HTTP 服务 https stackoverflow com questions 13222998
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • Clang 3.1 + libc++ 编译错误

    我已经构建并安装了 在前缀下 alt LLVM Clang trunk 2012 年 4 月 23 日 在 Ubuntu 12 04 上成功使用 GCC 4 6 然后使用此 Clang 构建的 libc 当我想使用它时我必须同时提供 lc
  • 堆栈溢出:堆栈空间中重复的临时分配?

    struct MemBlock char mem 1024 MemBlock operator const MemBlock b const return MemBlock global void foo int step 0 if ste
  • 在 ASP.NET 5 中使用 DI 调用构造函数时解决依赖关系

    Web 上似乎充斥着如何在 ASP NET 5 中使用 DI 的示例 但没有一个示例显示如何调用构造函数并解决依赖关系 以下只是众多案例之一 http social technet microsoft com wiki contents a
  • 使用 \r 并打印一些文本后如何清除控制台中的一行?

    对于我当前的项目 有一些代码很慢并且我无法使其更快 为了获得一些关于已完成 必须完成多少的反馈 我创建了一个进度片段 您可以在下面看到 当你看到最后一行时 sys stdout write r100 80 n I use 80覆盖最终剩余的
  • while 循环中的 scanf

    在这段代码中 scanf只工作一次 我究竟做错了什么 include
  • 控件的命名约定[重复]

    这个问题在这里已经有答案了 Microsoft 在其网站上提供了命名指南 here http msdn microsoft com en us library xzf533w0 VS 71 aspx 我还有 框架设计指南 一书 我找不到有关
  • 如何序列化/反序列化自定义数据集

    我有一个 winforms 应用程序 它使用强类型的自定义数据集来保存数据进行处理 它由数据库中的数据填充 我有一个用户控件 它接受任何自定义数据集并在数据网格中显示内容 这用于测试和调试 为了使控件可重用 我将自定义数据集视为普通的 Sy
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • 什么时候虚拟继承是一个好的设计? [复制]

    这个问题在这里已经有答案了 EDIT3 请务必在回答之前清楚地了解我要问的内容 有 EDIT2 和很多评论 有 或曾经 有很多答案清楚地表明了对问题的误解 我知道这也是我的错 对此感到抱歉 嗨 我查看了有关虚拟继承的问题 class B p
  • 如何查看网络连接状态是否发生变化?

    我正在编写一个应用程序 用于检查计算机是否连接到某个特定网络 并为我们的用户带来一些魔力 该应用程序将在后台运行并执行检查是否用户请求 托盘中的菜单 我还希望应用程序能够自动检查用户是否从有线更改为无线 或者断开连接并连接到新网络 并执行魔
  • 为什么编译时浮点计算可能不会得到与运行时计算相同的结果?

    In the speaker mentioned Compile time floating point calculations might not have the same results as runtime calculation
  • 如何在Xamarin中删除ViewTreeObserver?

    假设我需要获取并设置视图的高度 在 Android 中 众所周知 只有在绘制视图之后才能获取视图高度 如果您使用 Java 有很多答案 最著名的方法之一如下 取自这个答案 https stackoverflow com a 24035591
  • 如何防止用户控件表单在 C# 中处理键盘输入(箭头键)

    我的用户控件包含其他可以选择的控件 我想实现使用箭头键导航子控件的方法 问题是家长控制拦截箭头键并使用它来滚动其视图什么是我想避免的事情 我想自己解决控制内容的导航问题 我如何控制由箭头键引起的标准行为 提前致谢 MTH 这通常是通过重写

随机推荐

  • 快速对数计算

    所有代码都在同一台 Linux 机器上运行 在Python中 import numpy as np drr abs np random randn 100000 50 timeit np log2 drr 10 个循环 3 个循环中最好的
  • 解释 @property id 的语法

    在使用类似的东西编写委托时 我看到很多代码引用 property nonatomic weak id
  • 图像类型 int16 到 uint8 的转换

    我有一个具有数据类型的图像int16 因此 当我必须将其范围转换为 0 255 时 我有两种方法可以在 Python 中实现 1 Use numpy uint8直接运行 2 使用OpenCVcv2 normalize函数范围为 0 255
  • 通过互联网连接套接字失败

    目录 Preface 服务器端代码 客户端代码 本地计算机示例 成功的 互联网网络示例 不成功 我的可能性考虑 Preface 我从 MSDN 的类库示例中获取这些代码 所以它必须正确工作 是的 我说对了一部分 在我的电脑上运行就成功了 但
  • 寻的导弹,它们如何工作?

    我正在尝试创造什么 一个会向玩家发射导弹的物体 如果它与玩家相撞 玩家就会死亡 问题 导弹如何朝玩家移动 如何使导弹移动 使其不会立即直接移向玩家 以一定角度缓慢移动 我有一个公式 让鼠标成为 玩家 而导弹则朝它飞去 mouse Mouse
  • 使用java 7语法编译为java 5

    有没有办法使用 java 7 语法并生成适用于 1 5 的字节码 据我所知 选项 target and source不可能有什么不同 检查是否没有使用新的 API 也很好 但并不重要 不它不是 据我所知 不同 source and targ
  • Mule ESB 中的重连策略

    我正在尝试验证文档中提到的 Mule ESB 中的重新连接策略 我已将标准重新连接策略设置为重试次数为 5 次并设置一些超时 我的终点无法到达 因为故意停止它来测试场景 我在 Mule 控制台中有一个例外 异常堆栈是 1 连接被拒绝 con
  • 为什么我们会在每台计算机安装中收到非广告快捷方式的 ICE57 错误?

    此问题询问 ICE57 验证器之一是否会创建误报错误报告 我正在使用 WIX 3 9 生成安装程序 我想要使 用非广告快捷方式的每台计算机安装 此 WXS 示例安装一个文本文件和打开该文本文件的快捷方式
  • MongoDB $set 不更新记录

    我正在使用 PHP PECL 扩展尝试 MongoDB 但是我很难让某个更新查询正常工作 我在 SO 上四处寻找答案 但运气不佳 我创建了一个基本集合 m new Mongo collection m gt testdb gt testco
  • 如何在通知视图中制作倒计时器?

    我想出了如何使用来制作自定义视图RemoteViews http developer android com reference android widget RemoteViews html班级 我也知道怎么用Chronometer ht
  • 一个大的 javascript 文件还是多个较小的文件? [复制]

    这个问题在这里已经有答案了 好的 我有一个大小合理的项目 其中使用 jquery 主干和其他几个 javascript 库 我想知道是否应该为我的 javascript 库准备一个文件 为我的自定义代码准备另一个文件 或者一堆单独的 jav
  • HTTP/1.0 还在使用吗?

    比如说写一个HTTP服务器 客户端 支持HTTP 1 0有多重要 如今它还在任何地方使用吗 Edit 我不太关心 HTTP 1 0 的有用性 重要性 而是关心它的数量software实际上将其用于现实世界中的非内部 例如 单元测试是内部使用
  • 如何在Python中的段落中加入换行符

    我有一些采用以下格式的文本 r n 1 r n par1 par1 par1 r n r n par1 par1 par1 r n r n 2 r n r n par2 par2 par2 我想做的是将它们连接成段落 以便最终结果是 1 p
  • 如何在 React 组件中使用 @types/redux-form 定义的类型与 Field 和 FieldArray?

    我正在使用 React Redux Redux Form 和 TypeScript 开发应用程序 我正在努力使用包 types redux form 定义的类型 绝对打字 https github com DefinitelyTyped D
  • MailChimp 内容阻止拖放不起作用

    我必须在 MailChimp 服务中编辑现有的自定义模板 其中内容块的拖放功能不起作用 模板有很多嵌套表 因此我联系了他们的支持人员 他们的回复是某些块是嵌套的 可能会导致冲突 为了制作简单的测试用例场景 我删除了大部分代码 样式 只留下一
  • Onclick普通按钮正在提交表单

    SCENARIO 我有一个java带有长表单的 JSP 视图 这工作得很好 我可以通过在任何输入字段中按 Enter 键或使用提交按钮来提交表单 新要求 在一部分中 我必须添加按钮来替换一些
  • WPF System.ComponentModel.Win32Exception(0x80004005):无效的窗口句柄

    我在 WPF 上收到以下错误 我正在使用 MVVM 数据绑定到窗口上的 DataContext CollectionViewSources 视图模型和视图中有太多代码需要发布 但我想知道在哪里可以找到它 因为没有出现行号 该窗口使用 WPF
  • 拒绝浏览器通知权限

    根据规格 https developer mozilla org en US docs Web API Notification requestPermission 您可以提示浏览器允许用户授予或拒绝浏览器通知 一旦用户授予权限 是否也可以
  • 防止负载均衡器在长时间运行期间超时

    我使用 ASP NET MVC 4 接受最大 30 mb 的视频上传 视频上传到网站后 视频就会使用 HttpWebRequest 发布到第三方 Web 服务 向第三方服务的上传必须完成并返回响应 然后我的网站才能向浏览器返回响应 在 Ra
  • 编写我自己的 init 可执行文件

    我想创建自己的 init 并为下雪的周末带来一些 Linux 乐趣 我知道 内核使用 rootfs 启动 并在加载驱动程序和安装磁盘后将流程提供给 sbin init 我下载了ubuntu云镜像并尝试使用kvm直接启动内核 如下所示 kvm