编写我自己的 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 可执行文件 的相关文章

随机推荐

  • 快速对数计算

    所有代码都在同一台 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