我有一个“最小的 Linux”实验,我必须使系统尽可能接近裸内核,因此我需要编写自己的init
.我知道如何执行关闭、重新启动和控制台初始化,init
每次都在 PID 1 上运行,并且它要么初始化帧缓冲区,要么有一个执行此操作的脚本。我对Linux很熟悉,但是网上没有任何资料可以写,init
除了一个极小的初始化控制台,运行printf
3次,然后退出的信息(关联init
)和一个关于关闭/重启问题的Python (关联)。我需要的是帧缓冲区初始化方面的帮助。我当前的代码如下。
int init_main(int argc, char **argv)
{
// PID handler
if (getpid() != 1)
{
pidn1: if (getppid() == 1)
{
execl("/sbin/initrq", "-i" 0);
return;
}
}
reboot(RB_DISABLE_CAD);
// Console initialization
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);
// Print a message
printf("CUSTOM LINUX INIT\nNo framebuffer init\n");
// Run initrq.
fork() // This forked copy will not be PID 1, so that receives an execl("/sbin/initrq", 0)
if (getpid() != 1) goto pidn1; // Fork behavior independency
// Create shutdown/reboot agent FIFO
int fifofd = mkfifo("/etc/cinit-rs", S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | IWOTH);
uint8_t buf[2];
// Main loop
for (;;)
{
if (read(fifofd, buf, 2) < 2)
{
sleep(1);
continue;
}
if (buf[0] == 0x4A)
{
if (buf[1] == 0xF0)
{
init_shutdown(0);
}
if (buf[1] == 0xFF)
{
init_shutdown(1);
}
}
}
}
void init_shutdown(int rscmd)
{
execl("/sbin/initrq", rscmd ? "-r" : "-s", 0);
}
让我澄清一下initrq
。initrq
是运行使用特定方法定义的脚本的进程init
(该方法在实现中定义initrq
)。如果initrq
收到-i
,它将运行启动脚本。如果initrq
接收到-s
或,则它运行关闭脚本,然后分别根据是否是或-r
来关闭或重新启动。-s
-r