2017-06-28 18:41:12 u014250437 阅读数 247

前段时间买了一块2451(友善之臂)的开发板,昨天想编译下写的驱动程序,但是出现如下的错误:

cc1: error: unrecognized command line option "-mlittle-endian"
cc1: error: unrecognized command line option "-mapcs"
cc1: error: unrecognized command line option "-mno-sched-prolog"
cc1: error: unrecognized command line option "-mabi=aapcs-linux"
cc1: error: unrecognized command line option "-mno-thumb-interwork"
arch/arm/kernel/asm-offsets.c:1: error: bad value (armv5t) for -march= switch
arch/arm/kernel/asm-offsets.c:1: error: bad value (strongarm) for -mtune= switch


此错误是因为没有加载交叉编译器。有同学可能会说我已经安装交叉编译器了啊!  你虽然安装了,但是你没有修改内核根目录下的makefile文件,所以不行。


解决方案:

先编译拷贝到虚拟机上的内核(将开发板的内核拷贝过来)编译。编译之前在内核根目录下使用make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-命令CROSS_COMPILE的值你要是不知道可以用arm-linux-gcc -v命令查看,如图所示,Target后面的值就是了。使用完make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-命令后就可以编译内核了。

2019-06-15 16:22:37 myselfzhangji 阅读数 276

一 why
记录下移植内核过程中,出现的错误以及解决问题办法
a. 加载内核时,提示提示空分区名(empty pattition name)
原因,分区被异常擦掉了,解决办法
(1). 在uboot下输入nand erase
(2). 重新烧写uboot、kernel、以及文件系统

2013-12-01 22:06:39 trochiluses 阅读数 3827

摘要:在进行linux内核开发中,编译内核是一项基本技能。在这项技能中,可以说,无法启动内核的时候,也是我们能够学习最多的时候。本文主要总结linux内核编译过程中出现的各种错误和解决方法。既有针对原生态的内核,也有针对发行版的内核。


本文来源:linux 内核编译实战——内核编译错误汇总


1.config阶段


1)由于在本机上,已经存在一个内核。当我们再次编译内核的时候,由于内核版本相同,导致新内核覆盖原来的内核。

解决方法:修改.config中的版本号码LOCALVERSION


2.make阶段


1)centos 6.4 make阶段,出现提示信息:crypto/signature/ksign-publickey.c: key.h: No such file or directory

解决方法:

1) Select "Enable loadable module support", then "Module signature verification (EXPERIMENTAL)". Disable it.
2) Then go back to the main menu, select "Cryptographic API" then "In-kernel signature checker (EXPERIMENTAL)" and disable that one too.
Then go back again, save your config and make your kernel. At least, it will pass this phase successfully.


3.make install阶段


1)centOS 6.4 make install阶段,出现错误信息:ERROR: modinfo: could not find module vmhgfs


原因分析:在make install时,为了让新内核中不缺少所需module,会先检查当前系统已经加载了的module(lsmod命令可查看),然后对比新安装的内核模块,如果新的内核模块中缺少一些module(和当前lsmod命令的输出做对比),就会报“ERROR: modinfo: could not find module power_meter”这样的错误信息。

具体来说,缺少相应module而报错,大致可分为3种情况:
1. 确实是缺少了某个module,其解决方法是:如果报的module对于你来说是有用,检查编译kernel时的.config文件,加上对应的配置(配为=m),重新编译和安装modules即可;如果你觉得这个module没啥用,大可不必管它了。

2. 新编译的kernel已经将该选项编译进kernel了(.config中选择为=Y),从而不需要生成这个module的.ko文件,系统找不到对应的.ko文件,但是已经在新内核中了,不必理会这个报错。例如,上面的“ERROR: modinfo: could not find module ext4”是因为我将EXT4文件系统模块编译为built-in了,如下:

3. 模块的名称变了,用当前系统lsmod命令查找的模块名称,在新编译的内核中找不到module了。只需要检查确认即可,如这里的“ERROR: modinfo: could not find module power_meter”就是这种类型,检查方式如下:

4.在centos 6.4中,还有可能存在另外一种情况:用于没有运行make modules

在原生态的内核中,运行make all就包含make modules,但是centOS却不是这样,需要运行make modules来编译模块。


更新中...

2016-01-25 12:25:33 guoxiaojie_415 阅读数 5013

Linux内核在线升级

准备工作

1 查看Linux内核发行版本的命令

  • uname -a
  • cat /etc/issue
  • cat /proc/version

2 Linux内核版本介绍

Linux内核版本有两种,即稳定版和开发版,版本号由3个数字组成,r.x.y

  • r:表示主版本号
  • x:次版本号,奇数表示开发中的版本,偶数表示稳定版本;
  • y:修订版本号,表示修改的次数

Linux内核主页上有stable、longterm邓版本,longterm是比stable更稳定的版本,会长时间更新。

3 获取Linux内核

本文实验平台为CentOS 5.5 内核版本为2.6.18,欲升级到2.6.32.69。
在Linux内核主页(http://www.kernel.org)下载Linux内核,

wget https://cdn.kernel.org/pub/linux/kernel/v2.6/longterm/v2.6.32/linux-2.6.32.69.tar.xz --no-check-certificate   
//添加--no-check-certificate,否则可能出现证书解析错误

4 安装编译内核所需要的软件

yum grouplist // 查看已经安装和未安装的软件包组,以判断是否要安装相应的开发环境和开发库;
yum groupinstall "Development Tools"  //一般是安装这两个软件包组,这样做会确定你拥有编译时所需的一切工具
yum install ncurses-devel //使make *config命令可执行
yum install qt-devel //如果你没有 X 环境,这一条可以不用

升级Linux内核

1 产生一个内核配置文件

//xz 的文件解压比较特殊,需要先用xz解压成rar文件后,再使用tar解压
xz -d linux-2.6.32.69.tar.xz //解压*.tar.xz ,若无xz,需要先安装,yum -y xz
tar -xvf linux-2.6.32.69.tar //解压*.tar
cd linux-2.6.32.69
make menuconfig // 图形化的

若依然使用之前的内核配置,使用如下命令即可。

make oldconfig // 使用当前内核的配置
结果如下:
ripts/kconfig/conf -o arch/x86/Kconfig
#
# configuration written to .config
#

但该过程中,你可能仍然需要手动设置新的配置,直接“回车”选择默认即可。你也可以不手动配置,并接受默认配置,执行以下命令即可,

sh -c 'yes "" | make oldconfig' //使用当前内核的配置,新配置,使用默认

上述步骤执行完成后会生成一个.config文件,即编译内核所需要的配置文件。编辑生成的 .config 文件,将CONFIG_SYSFS_DEPRECATED_V2 改成CONFIG_SYSFS_DEPRECATED_V2=y,否则会出现“Kernel panic – not syncing: Attempted to kill init!”的错误。

2 编译并安装内核

make  // 编译过程大约需要半个小时
make modules_install install

3 修改Grub引导顺序

vim /etc/grub.conf
或者
vim /boot/grub/grub.conf

升级内核之前/boot/grub/grub.conf的内容

升级内核之后/boot/grub/grub.conf的内容

4 重启 reboot 或者 init 6

可能出现的错误如下:

错误1:Kernel panic – not syncing: Attempted to kill init!

mount: could not find filesystem ‘/dev/root’
setuproot: moving /dev failed: No such file or directory
setuproot: error mounting /proc: No such file or directory
setuproot: error mounting /sys: No such file or directory
switchroot: mount failed: No such file or directory
Kernel panic – not syncing: Attempted to kill init!

启动错误

解决方法:将config文件中原本被注释掉的CONFIG_SYSFS_DEPRECATED_V2 改成CONFIG_SYSFS_DEPRECATED_V2=y
原因: 修改这项是因为旧版的mkinitrd及其nash在内核没有CONFIG_SYSFS_DEPRECATED_V2参数时默认使用旧版sysfs路径格式,从而在新内核下无法正确访问/sys内的硬盘信息节点。主要是解决”mount:could not find filesystem ‘/dev/root’”这样的错误。

错误2:insmod: error inserting ‘/lib/dm-region-hash.ko’ : -1 File exists

// 解压initrd文件
cp initrd-2.6.32.69.img /tmp
cd /tmp/
mkdir newinit
cd newinit/
zcat ../initrd-2.6.32.69.img | cpio -i

// 编辑init
vim init
注释掉下面四行:
echo "Loading dm-region-hash.ko module"
insmod /lib/dm-region-hash.ko
echo "Loading dm-region-hash.ko module"
insmod /lib/dm-region-hash.ko

//重新打包initrd
find .|cpio -c -o > ../initrd
cd ..
gzip -9 < initrd > initrd-2.6.32.69-new.img
cd /boot/
mv initrd-2.6.32.69.img initrd-2.6.32.69.img.bak
mv /tmp/initrd-2.6.32.69-new.img initrd-2.6.32.69.img

*说明:出现错误2时,系统仍然可以启动,但会出现“insmod: error inserting ‘/lib/dm-region-hash.ko’ : -1 File exists” 的提示,通过上述配置可以将错误提示去除掉。

5 查看内核版本 uname -r,升级成功

参考链接

1 How to upgrade the kernel on CentOS
2 CentOS 6.5 升级内核到 3.10.28
3 centos5.5简单内核升级
4 What does “make oldconfig” do exactly in the Linux kernel makefile?
5 Linux内核升级方法详解
6 centos内核升级文档

2017-03-06 15:52:40 zifehng 阅读数 2232

内核错误码

在调用内核api发生异常时通常会返回一个负数值,不同的出错情况,负数值也不同,这些数值就是内核中预定义的错误码(errno),了解这些错误码的含义可以让我们推测出错的原因,从而提高开发效率。

errno-base.h中定义了内核中常见的错误码:

/* 
 * kernel version: linux-4.9.13
 * File path: include/uapi/asm-generic/errno-base.h
 */

#ifndef _ASM_GENERIC_ERRNO_BASE_H
#define _ASM_GENERIC_ERRNO_BASE_H

#define EPERM        1  /* Operation not permitted */
#define ENOENT       2  /* No such file or directory */
#define ESRCH        3  /* No such process */
#define EINTR        4  /* Interrupted system call */
#define EIO          5  /* I/O error */
#define ENXIO        6  /* No such device or address */
#define E2BIG        7  /* Argument list too long */
#define ENOEXEC      8  /* Exec format error */
#define EBADF        9  /* Bad file number */
#define ECHILD      10  /* No child processes */
#define EAGAIN      11  /* Try again */
#define ENOMEM      12  /* Out of memory */
#define EACCES      13  /* Permission denied */
#define EFAULT      14  /* Bad address */
#define ENOTBLK     15  /* Block device required */
#define EBUSY       16  /* Device or resource busy */
#define EEXIST      17  /* File exists */
#define EXDEV       18  /* Cross-device link */
#define ENODEV      19  /* No such device */
#define ENOTDIR     20  /* Not a directory */
#define EISDIR      21  /* Is a directory */
#define EINVAL      22  /* Invalid argument */
#define ENFILE      23  /* File table overflow */
#define EMFILE      24  /* Too many open files */
#define ENOTTY      25  /* Not a typewriter */
#define ETXTBSY     26  /* Text file busy */
#define EFBIG       27  /* File too large */
#define ENOSPC      28  /* No space left on device */
#define ESPIPE      29  /* Illegal seek */
#define EROFS       30  /* Read-only file system */
#define EMLINK      31  /* Too many links */
#define EPIPE       32  /* Broken pipe */
#define EDOM        33  /* Math argument out of domain of func */
#define ERANGE      34  /* Math result not representable */

#endif

内核错误指针

通常如果一个函数返回值是指针类型,在调用出错的情况下会返回NULL指针,但Linux内核对指针返回值作了更精妙的处理,使其与错误码相关联,从而让出错情况能通过返回的指针体现出来。在内核中,有以下三种指针:

  • 有效指针
  • 空指针(NULL)
  • 错误指针

其中错误指针被定义为指向内核空间保留区域(addr:0xffff000~0xffffffff, size: 4K)的指针

内核空间保留区域

在有限的内核空间内,最后一页4K大小的地址被保留,并和内核定义的系列错误码相关联,指示了对应的出错情况,如果一个指针指向该页地址范围即被定义为错误指针。内核提供了错误指针相关的api:

/* 
 * kernel version: linux-4.9.13
 * File path: include/linux/err.h
 */

......

#define MAX_ERRNO   4095

#define IS_ERR_VALUE(x) unlikely((unsigned long)(void *)(x) >= (unsigned long)-MAX_ERRNO)

/* 将错误码转为错误指针 */
static inline void * __must_check ERR_PTR(long error)
{
    return (void *) error;
}

/* 将错误指针转为错误码 */
static inline long __must_check PTR_ERR(__force const void *ptr)
{
    return (long) ptr;
}

/* 判断指针是否为错误指针 */
static inline bool __must_check IS_ERR(__force const void *ptr)
{
    return IS_ERR_VALUE((unsigned long)ptr);
}

static inline bool __must_check IS_ERR_OR_NULL(__force const void *ptr)
{
    return unlikely(!ptr) || IS_ERR_VALUE((unsigned long)ptr);
}

......

  
内联函数IS_ERR(),用来判断指针是否错误,将其一一展开:

IS_ERR(ptr)
    |
    IS_ERR_VALUE(ptr)
        |
        unlikely((unsigned long)(void *)(x) >= (unsigned long)-MAX_ERRNO)
            |
            unlikely((unsigned long)(void *)(x) >= (unsigned long)-4095)

表达式(unsigned long)-4095的值就是0xfffff000,如果一个指针指向内核空间保留
区域(0xfffff000~0xffffffff),IS_ERR()将返回flase,该指针即错误指针。

内联函数PTR_ERR()与ERR_PTR(),提供错误指针与错误码相互转换的功能,涉及到类型强制转换,错误指针指向地址范围为0xfffff000~0xffffffff,因此转成错误码范围为-4096~-1。

在内核开发中,如果调用返回值为指针的函数,出错判断条件不能简单地写为“if (ptr == NULL)”,正确的做法是先使用IS_ERR()或者IS_ERR_OR_NULL()判断指针返回值,然后再用PTR_ERR()将错误指针转为错误码,最后执行相应的出错处理。例如字符设备驱动开发中常见的device_create()函数,应该使用如下出错判断及处理:

    dev = device_create(class, NULL, devno, NULL, DEVICE_NAME);
    if (IS_ERR(dev)) {
        errno = PTR_ERR(dev);
        return errno;
    }

linux内核下载

阅读数 394

Linux内核错误 修复

阅读数 4038

没有更多推荐了,返回首页