linux启动根文件失败报错:进程退出exitcode,Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

进程退出的 exitcode

错误信息

内核打印

1
Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b

分析

出错位置

1
2
3
panic("Attempted to kill init! exitcode=0x%08x\n",
    father->signal->group_exit_code ?:
        father->exit_code);

kernel/exit.c

exit_cede 赋值

1
2
3
4
5
6
7
8
void do_exit(long code)
{
	...
	 tsk->exit_code = code;
	...
	exit_notify(tsk, group_dead);
	...
}

函数调用关系:

1
2
3
4
exit_notify
	|-> forget_original_parent(tsk);
				|-> find_new_reaper(father);
							|-> "Attempted to kill init! exitcode=0x%08x\n"

错误来源

在 Android 系统中,linux 内核启动过程中,进入用户空间后,init 进程执行过程中出现该错误

由于在用户空间引起的内核错误,因此只能通过系统调用产生

1
2
3
4
SYSCALL_DEFINE1(exit, int, error_code)
{
    do_exit((error_code&0xff)<<8);
}

在进入内核是 do_exit 取了用户空间传入的错误码的低8位

进程退出的错误码

在系统中的进程在正常和非正常退出时,都有一个表示当前进程退出状态的标识,即退出码

查看进程退出码

退出码代表的是一个进程退出的状态码,可以使用 wait 函数进行查看。

1
void _exit(int status),

status 表明了进程终止时的状态。当子进程使用_exit () 后,父进程如果在用 wait () 等待子进程,那么 wait () 将会返回 status 状态,注意只有 status 的低 8 位(0~255)会返回给父进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>

int main(void)
{
    int count = 1;
    int pid;
    int status;

    pid = fork( );
    printf("pid=%d\n", pid);

    if(pid < 0) {
        perror("fork error : ");
    } else if(pid == 0) {
        printf("This is son, his count is: %d (%p). and his pid is: %d\n",
                ++count, &count, getpid());
        sleep(3);
        _exit(0);
    } else {
        pid = wait(&status);

        printf("This is father, his count is: %d (%p), his pid is: %d, son exit status: %d[%08x]\n",
                count, &count, getpid(), status, status);
    }

    return 0;
}

正常退出结果:

1
2
3
4
5
=====>$./a.out
pid=4018
pid=0
This is son, his count is: 2 (0x7fff19658714). and his pid is: 4018
This is father, his count is: 1 (0x7fff19658714), his pid is: 4017, son exit status: 0[00000000]

在子进程 sleep 时将其 kill 掉的结果:

1
2
3
4
5
6
7
8
9
10
=====>$./a.out &
[1] 4066
00:11 [xxx@machine]~/work/MyCode/systemcall/test
=====>$pid=4067
pid=0
This is son, his count is: 2 (0x7ffe19987d04). and his pid is: 4067

00:11 [xxx@machine]~/work/MyCode/systemcall/test
=====>$kill 4067
This is father, his count is: 1 (0x7ffe19987d04), his pid is: 4066, son exit status: 15[0000000f]

在进程正常退出时,子进程的状态码是 0,而 kill 掉后变为了 15.

注:此时如果在 linux 终端下使用 echo $?, 获取的仅仅该进程的 main 函数的返回值。

退出码的含义

根据前面分析,在进程调用_exit 退出时,是通过 exit 系统调用实现的,而这里的 0 和 15, 就是系统调用 exit 的参数 error_code

进程的退出状态不等于退出码,程退出时候的状态码是 8 位,高 4 位存储退出码,低 4 位存储导致进程退出的信号标志位

网上有人说 16 位,分别是高八位和低八位,还需确认

根据这段话的描述,之前测试中子进程的退出状态 0 和 15 中,退出码均为 0, 而退出时的 singal 不同,正常退出时为 0,kill 掉后变为 15

制造段错误

在测试 case 中的子进程中,制造一个段错误,根据此时的分析子进程退出的状态码中的 signal 应该代表段错误
子进程中添加:

1
2
int *a;
*a = 3;

测试结果:

1
2
3
4
5
=====>$./a.out
pid=4500
pid=0
This is son, his count is: 2 (0x7fff54e86d1c). and his pid is: 4500
This is father, his count is: 1 (0x7fff54e86d1c), his pid is: 4499, son exit status: 139[0000008b]

此时子进程的退出码=8而 signal=b

信号

linux 内核中 x86 的信号列表:

1
2
#define SIGSEGV     11
#define SIGTERM     15

arch/x86/include/uapi/asm/signal.h

信号行为产生原因
SIGTERM请求中断kill () 可以发 SIGTERM 过去;kill 命令默认也使用 SIGTERM 信号
SIGSEGV无效内存引用段错误

总结

进程在退出时都会将自己当前的状态告诉内核,而此时的状态码包含两种含义:

  • 高 4 位代表当前进程的退出码
  • 低 4 位代表使当前进程退出所使用的信号

在本文最开始提到的错误也是由于 SIGSEGV 无效内存引用引起的。

mips 架构下的信号列表:

1
#define SIGTERM     15  /* Termination (ANSI).  */

arch/mips/include/uapi/asm/signal.h

参考:

  1. linux 子进程退出状态值解析:waitpid () status 意义解析
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个错误是一个Linux内核恐慌(kernel panic)错误,意味着Linux无法继续执行,并需要重新启动。在这种情况下,内核已经尝试杀死初始化进程init),这是Linux系统启动的第一个进程。导致内核恐慌的原因可能是由于硬件故障、内存错误或驱动程序问题等多种原因引起的。在使用buildroot构建嵌入式Linux系统时,这种错误通常可能是由于不兼容的驱动程序或未正确配置系统而引起的。为了解决这种问题,首先需要重新启动系统,并尝试对系统进行诊断以确定错误的具体原因。可以通过检查系统日志和内存转储文件等手段来诊断内核恐慌错误。如果问题是由于不兼容的驱动程序引起的,需要更新驱动程序或更改构建设置以使用兼容的驱动程序。如果问题是由于配置错误引起的,需要重新检查系统配置以确保正确配置。另外,建议在构建Linux系统之前了解Linux内核的基础知识,以便更好地理解内核恐慌错误的特征和原因,并能够快速解决此类问题。 ### 回答2: Buildroot是一个用于构建嵌入式Linux系统的工具。当出现"kernel panic - not syncing: attempted to kill init!"时,意味着引导过程中发生了严重错误,导致系统无法继续运行。 最常见的原因是内核与硬件不兼容,这意味着内核无法正确识别或配置硬件设备。可能需要调整内核配置以支持特定硬件设备,或者使用更适合的内核版本。 另一种可能的原因是文件系统损坏或不正确挂载。这可能是由于文件系统镜像文件被损坏或不正确生成而引起的。解决方法是重新生成文件系统镜像或更换正确的文件系统镜像文件。 此外,在构建rootfs时如果不小心将一些错误的配置选项或文件添加到文件系统中,也可能导致kernel panic。需要审查构建rootfs时使用的配置选项和文件以确保它们是正确的。 最后,系统内存问题也可能导致此错误。确保系统具有足够的可用内存以运行所需的软件包和驱动程序。 综上所述,出现kernel panic - not syncing: attempted to kill init!时,最好的方法是仔细检查内核配置、文件系统镜像文件和rootfs中的配置选项和文件,并确保系统具有足够的可用内存以支持运行所需的软件包和驱动程序。 ### 回答3: buildroot是一个开源的嵌入式Linux构建工具,我们可以使用它来制作自定义嵌入式系统的镜像。在使用buildroot构建嵌入式系统的过程中,可能会出现一些问题,比如“kernel panic - not syncing: attempted to kill init!”这个错误。 这个错误通常是由于内核在尝试杀死init进程时发生的问题触发的。init进程Linux系统中的第一个进程,是由内核启动的,它负责初始化系统并启动其他所有进程。如果init进程启动或执行期间出现问题,整个系统将停止工作并且引发kernel panic。 当出现这种错误时,应该按照以下步骤来解决: 1. 检查构建脚本:检查buildroot构建脚本中的配置选项是否正确,确保所有必需的选项都被正确配置。 2. 查看系统日志:在出现此错误时,系统日志应该记录相关错误信息。查看系统日志以确定导致问题的原因。 3. 检查root文件系统:确保root文件系统已正确构建并已正确挂载。如果root文件系统中可能缺少文件或存在损坏的文件,则可能会引发该错误。 4. 更新内核:更新内核可以解决一些与内核相关的问题。使用buildroot提供的选项更新内核。 5. 检查硬件:该错误也可能由硬件问题引起。请检查硬件是否正常运行,例如RAM是否存在问题。 总之,出现kernel panic - not syncing: attempted to kill init!错误时,应该先检查构建脚本、系统日志、root文件系统、内核和硬件,以找出导致错误的原因并进行相应的修复。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值