xz -d linux-4.15.6.tar.xz
tar -xvf linux-4.15.6.tar
进行解压操作,就可以进行移植操作了。
1.修改Makefile文件:
-ARCH ?= $(SUBARCH)
-CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
+ARCH ?= arm
+CROSS_COMPILE ?= arm-linux-gnueabi-
在3.4.2内核中交叉编译设置arm-linux-就可以编译,这里不知为何会出错,网上查找设置成arm-linux-gnueabi-就可以,我的arm-linux-gcc 的版本是4.3.2,arm-linux-gnueabi-gcc的版本是4.7.3。需要注意的是arm和arm-linux-gnueabi-之后不能添加任何的空格否则会出现莫名其妙的错误。
复制arch/arm/config/s3c2410_defconfig文件到内核源码根目录
2.修改晶振频率
linux-4.15.6/arch/arm/mach-s3c24xx/mach-smdk2440.c 文件中
static void __init smdk2440_init_time(void)
{
//s3c2440_init_clocks(16934400);
s3c2440_init_clocks(12000000);
samsung_timer_init();
}
修改时钟频率为12M,否则串口输出将为乱码
3.修改mtd分区
/linux-4.15.6/arch/arm/mach-s3c24xx/common-smdk.c文件中
/* NAND parititon from 2.4.18-swl5 */
static struct mtd_partition smdk_default_nand_part[] = {
[0] = {
.name = "bootloader",
.size = SZ_256K,
.offset = 0,
},
[1] = {
.name = "params",
.offset = MTDPART_OFS_APPEND,
.size = SZ_128K,
},
[2] = {
.name = "kernel",
.offset = MTDPART_OFS_APPEND,
.size = SZ_4M,
},
[3] = {
.name = "rootfs",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
}
};
这个要跟uboot的mtdparts相对应,由于新的kernel比较大,原先的2M不够,故这里修改为4M。设置uboot变量用set 命令,后需要saveenv进行保存变量。
uboot环境变量:
baudrate=115200
ethaddr=08:00:3e:26:0a:5b
serverip=192.168.7.11
netmask=255.255.255.0
mtdids=nand0=nandflash0
bootdelay=5
ipaddr=172.16.91.161
mtdparts=mtdparts=nandflash0:256k@0(bootloader),128k(params),4m(kernel),-(root)
machid=16a //s3c2440对应的id
filesize=1A7540
bootcmd=nand read 0x30008000 0x80000 0x500000
bootargs=init=/linuxrc console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=yaffs2 rw mem=64M
nand=read 30000000 kernel;bootm 30000000
stdin=serial
stdout=serial
stderr=serial
partition=nand0,0
mtddevnum=0
mtddevname=bootloader
Environment size: 525/131068 bytes
make s3c2410_defconfig配置生成.config文件,
make uImage在arch/arm/boot/目录底下生成uImage镜像文件。
4.分区设置好之后但是还是不能正常启动开发板,需要制作根文件系统。
4.1
下载busybox-1.20.0,make menuconfig
Busybox Settings ===>Build Options ====>Build Busybox as a static binary(no shared libs)编为静态库
4.2
修改Makefile 中的 ARCH 和 CROSS_COMPILE 为arm 和 arm-linux-
直接进行make,之后进行安装,执行命令
4.3
make CONFIG_PREFIX=/home/username/rootfs
安装到指定目录位置,这里装到roofs目录底下,将出现bin sbin usr 目录和linuxrc文件
修改linuxrc文件权限chmod 777 linuxrc。
4.4
创建etc lib proc tmp dev home mnt root sys等目录。
在etc文件夹底下创建fstab、inittab、mdev.conf等文件,创建文件夹init.d,并在其目录底下创建rcS文件。
inittab文件中的内容定义如下:
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
fstab文件中的内容定义如下:
#device mount-point type option dump fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
rcS文件中的内容定义如下:
PATH=/sbin:/bin:/usr/sbin:/usr/bin
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
mount -a
echo /sbin/mdev>/proc/sys/kernel/hotplug
mdev -s
各个文件的定义详解请见http://blog.csdn.net/mybelief321/article/details/10007719
4.5
添加库文件。查看自己的工具链环境变量echo $PATH,可得知其安装目录。如我的是/usr/local/arm/4.3.2/目录
/opt/jdk1.6.0_32/bin:/opt/jdk1.6.0_32/jre/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/arm/4.3.2/bin:
执行命令
cp /usr/local/arm/4.3.2/arm-none-linux-gnueabi/libc/armv4t/lib/*so* lib/ -d
-d :若来源文件为连结文件的属性(link file),则复制连结文件属性而非档案本身;
4.6
需要在dev中创建console 和null节点
mknod console c 5 1
mknod null c 1 3
权限要求加sudo
4.7
制作yaffs2根文件系统:
由于所使用的开发板NAND是256M的,需要使用工具mkyaffs2image-128M进行制作根文件系统。
cd /home/username/
mkyaffs2image-128M rootfs/ rootfs.yaffs2
制作根文件系统文件rootfs.yaffs2,通过uboot进行烧写进开发板。
而此时的开发板内核是没有支持yaffs2文件系统的,需要进行打补丁。
5.内核增加支持yaffs2文件系统
git clone git://www.aleph1.co.uk/yaffs2
下载yaffs2源码,进入yaffs2源码根目录,给4.15.6内核打补丁
./patch-ker.sh c m /your kernel path
将在内核fs目录底下添加yaffs2文件夹,fs目录底下的Makefile和Kconfig中添加对yaffs2文件系统的支持。
make menuconfig配置内核,
Location: │
│ -> File systems │
│ -> Miscellaneous filesystems (MISC_FILESYSTEMS [=y]) │
│ (2) -> yaffs2 file system support (YAFFS_FS [=y])
make clean清理下
make uImage重新生成内核镜像文件uImage
6.
由于yaffs2的更新脚步跟不上kernel的更新,所以在编译uImage时候会出现错误。
根据错误提示进行相应位置的修改即可:
iff -urN compare-linux-4.15.6/linux-4.15.6/fs/yaffs2/yaffs_vfs.c linux-4.15.6/fs/yaffs2/yaffs_vfs.c
--- compare-linux-4.15.6/linux-4.15.6/fs/yaffs2/yaffs_vfs.c 2018-03-03 09:19:34.482203584 +0800
+++ linux-4.15.6/fs/yaffs2/yaffs_vfs.c 2018-03-02 17:27:47.442250025 +0800
@@ -136,7 +136,8 @@
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26))
#define Y_INIT_TIMER(a) init_timer(a)
#else
-#define Y_INIT_TIMER(a) init_timer_on_stack(a)
+//#define Y_INIT_TIMER(a) init_timer_on_stack(a)//查看源码4.15.6并无该函数
+#define Y_INIT_TIMER(a) __init_timer_on_stack(a,NULL,0)
#endif
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 27))
@@ -262,6 +263,8 @@
#define YAFFS_NEW_GET_LINK 0
#endif
+#define CURRENT_TIME (current_kernel_time())
+
#define update_dir_time(dir) do {\
(dir)->i_ctime = (dir)->i_mtime = CURRENT_TIME; \
} while (0)
diff -urN compare-linux-4.15.6/linux-4.15.6/fs/yaffs2/yportenv.h linux-4.15.6/fs/yaffs2/yportenv.h
--- compare-linux-4.15.6/linux-4.15.6/fs/yaffs2/yportenv.h 2018-03-03 09:19:34.482203584 +0800
+++ linux-4.15.6/fs/yaffs2/yportenv.h 2018-03-02 17:36:59.814250025 +0800
@@ -59,6 +59,7 @@
#define YAFFS_ROOT_MODE 0755
#define YAFFS_LOSTNFOUND_MODE 0700
+#define CURRENT_TIME (current_kernel_time()) //查看3.4.2源码中该宏所对应函数
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
#define Y_CURRENT_TIME CURRENT_TIME.tv_sec
diff -urN compare-linux-4.15.6/linux-4.15.6/include/linux/timer.h linux-4.15.6/include/linux/timer.h
--- compare-linux-4.15.6/linux-4.15.6/include/linux/timer.h 2018-02-25 18:15:44.000000000 +0800
+++ linux-4.15.6/include/linux/timer.h 2018-03-02 17:29:01.310250025 +0800
@@ -19,7 +19,7 @@
unsigned long expires;
void (*function)(struct timer_list *);
u32 flags;
-
+ unsigned long data;//添加data成员变量
#ifdef CONFIG_LOCKDEP
struct lockdep_map lockdep_map;
#endif
diff -urN compare-linux-4.15.6/linux-4.15.6/include/linux/mtd/nand.h linux-4.15.6/include/linux/mtd/nand.h
--- compare-linux-4.15.6/linux-4.15.6/include/linux/mtd/nand.h 1970-01-01 08:00:00.000000000 +0800
+++ linux-4.15.6/include/linux/mtd/nand.h 2018-03-02 17:34:35.958250025 +0800 添加nand.h文件
错误可能不止这些,需要根据实际错误提示进行相应的修改。
用kernel3.4.2+网上下载的yaffs2源码(不是目前最新),make uImage过程中不会出现错误但是会有warnning提示,当时不在意,但是在挂载的时候就会出现致命性的错误。内核启动的提示:
[15:09:52]Booting Linux ...
[15:09:52]
[15:09:52]NAND read: device 0 offset 0x60000, size 0x400000
[15:09:52]
[15:09:58]Reading data from 0x45f800 -- 100% complete.
[15:09:58] 4194304 bytes read: OK
[15:09:58]## Booting image at 30007fc0 ...
[15:09:58] Image Name: Linux-3.4.2
[15:09:58] Created: 2018-03-02 6:24:08 UTC
[15:09:58] Image Type: ARM Linux Kernel Image (uncompressed)
[15:09:58] Data Size: 2088800 Bytes = 2 MB
[15:09:58] Load Address: 30008000
[15:09:58] Entry Point: 30008000
[15:09:59] Verifying Checksum ... OK
[15:09:59] XIP Kernel Image ... OK
[15:09:59]
[15:09:59]Starting kernel ...
[15:09:59]
[15:09:59]Uncompressing Linux... done, booting the kernel.
[15:10:00]Booting Linux on physical CPU 0
[15:10:00]Linux version 3.4.2 (root@xxxxxx) (gcc version 4.3.2 (Sourcery G++ Lite 2008q3-72) ) #2 Fri Mar 2 14:24:04 CST 2018
[15:10:00]CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177
[15:10:00]CPU: VIVT data cache, VIVT instruction cache
[15:10:00]Machine: SMDK2440
[15:10:00]Memory policy: ECC disabled, Data cache writeback
[15:10:00]CPU S3C2440A (id 0x32440001)
[15:10:00]S3C24XX Clocks, Copyright 2004 Simtec Electronics
[15:10:00]S3C244X: core 400.000 MHz, memory 100.000 MHz, peripheral 50.000 MHz
[15:10:00]CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on
[15:10:00]Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256
[15:10:00]Kernel command line: init=/linuxrc console=ttySAC0,115200 root=/dev/mtdblock3 rootfstype=yaffs2 rw mem=64M
[15:10:00]PID hash table entries: 256 (order: -2, 1024 bytes)
[15:10:00]Dentry cache hash table entries: 8192 (order: 3, 32768 bytes)
[15:10:00]Inode-cache hash table entries: 4096 (order: 2, 16384 bytes)
[15:10:00]Memory: 64MB = 64MB total
[15:10:00]Memory: 60648k/60648k available, 4888k reserved, 0K highmem
[15:10:00]Virtual kernel memory layout:
[15:10:00] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
[15:10:00] fixmap : 0xfff00000 - 0xfffe0000 ( 896 kB)
[15:10:00] vmalloc : 0xc4800000 - 0xff000000 ( 936 MB)
[15:10:00] lowmem : 0xc0000000 - 0xc4000000 ( 64 MB)
[15:10:00] modules : 0xbf000000 - 0xc0000000 ( 16 MB)
[15:10:00] .text : 0xc0008000 - 0xc03c2000 (3816 kB)
[15:10:00] .init : 0xc03c2000 - 0xc03e1000 ( 124 kB)
[15:10:00] .data : 0xc03e2000 - 0xc0409fc0 ( 160 kB)
[15:10:00] .bss : 0xc0409fe4 - 0xc0428f48 ( 124 kB)
[15:10:00]NR_IRQS:85
[15:10:00]irq: clearing pending ext status 00000300
[15:10:00]irq: clearing subpending status 00000003
[15:10:00]irq: clearing subpending status 00000002
[15:10:00]sched_clock: 32 bits at 200 Hz, resolution 5000000ns, wraps every 4294967291ms
[15:10:00]Console: colour dummy device 80x30
[15:10:00]Calibrating delay loop... 199.47 BogoMIPS (lpj=498688)
[15:10:00]pid_max: default: 32768 minimum: 301
[15:10:00]Mount-cache hash table entries: 512
[15:10:00]CPU: Testing write buffer coherency: ok
[15:10:00]Setting up static identity map for 0x302f5088 - 0x302f50e0
[15:10:00]gpiochip_add: registered GPIOs 0 to 23 on device: GPIOA
[15:10:00]gpiochip_add: registered GPIOs 32 to 47 on device: GPIOB
[15:10:00]gpiochip_add: registered GPIOs 64 to 79 on device: GPIOC
[15:10:00]gpiochip_add: registered GPIOs 96 to 111 on device: GPIOD
[15:10:00]gpiochip_add: registered GPIOs 128 to 143 on device: GPIOE
[15:10:00]gpiochip_add: registered GPIOs 160 to 167 on device: GPIOF
[15:10:00]gpiochip_add: registered GPIOs 192 to 207 on device: GPIOG
[15:10:00]gpiochip_add: registered GPIOs 224 to 234 on device: GPIOH
[15:10:00]gpiochip_add: registered GPIOs 256 to 271 on device: GPIOJ
[15:10:00]NET: Registered protocol family 16
[15:10:00]S3C Power Management, Copyright 2004 Simtec Electronics
[15:10:00]S3C2440: Initialising architecture
[15:10:00]S3C2440: IRQ Support
[15:10:00]S3C244X: Clock Support, DVS off
[15:10:00]bio: create slab <bio-0> at 0
[15:10:00]SCSI subsystem initialized
[15:10:00]usbcore: registered new interface driver usbfs
[15:10:00]usbcore: registered new interface driver hub
[15:10:00]usbcore: registered new device driver usb
[15:10:00]s3c-i2c s3c2440-i2c: slave address 0x10
[15:10:00]s3c-i2c s3c2440-i2c: bus frequency set to 97 KHz
[15:10:00]s3c-i2c s3c2440-i2c: i2c-0: S3C I2C adapter
[15:10:00]Advanced Linux Sound Architecture Driver Version 1.0.25.
[15:10:00]NET: Registered protocol family 2
[15:10:00]IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
[15:10:00]TCP established hash table entries: 2048 (order: 2, 16384 bytes)
[15:10:00]TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
[15:10:00]TCP: Hash tables configured (established 2048 bind 2048)
[15:10:00]TCP: reno registered
[15:10:00]UDP hash table entries: 256 (order: 0, 4096 bytes)
[15:10:00]UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[15:10:00]NET: Registered protocol family 1
[15:10:00]RPC: Registered named UNIX socket transport module.
[15:10:00]RPC: Registered udp transport module.
[15:10:00]RPC: Registered tcp transport module.
[15:10:00]RPC: Registered tcp NFSv4.1 backchannel transport module.
[15:10:00]jffs2: version 2.2. (NAND) ?2001-2006 Red Hat, Inc.
[15:10:00]msgmni has been set to 118
[15:10:00]io scheduler noop registered
[15:10:00]io scheduler deadline registered
[15:10:00]io scheduler cfq registered (default)
[15:10:00]Console: switching to colour frame buffer device 30x40
[15:10:00]fb0: s3c2410fb frame buffer device
[15:10:00]s3c2440-uart.0: ttySAC0 at MMIO 0x50000000 (irq = 70) is a S3C2440
[15:10:00]console [ttySAC0] enabled
[15:10:00]s3c2440-uart.1: ttySAC1 at MMIO 0x50004000 (irq = 73) is a S3C2440
[15:10:00]s3c2440-uart.2: ttySAC2 at MMIO 0x50008000 (irq = 76) is a S3C2440
[15:10:01]brd: module loaded
[15:10:01]loop: module loaded
[15:10:01]S3C24XX NAND Driver, (c) 2004 Simtec Electronics
[15:10:01]s3c24xx-nand s3c2440-nand: Tacls=2, 20ns Twrph0=6 60ns, Twrph1=2 20ns
[15:10:01]s3c24xx-nand s3c2440-nand: NAND soft ECC
[15:10:01]NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit)
[15:10:01]Scanning device for bad blocks
[15:10:01]Bad eraseblock 1403 at 0x00000af60000
[15:10:01]Bad eraseblock 1695 at 0x00000d3e0000
[15:10:01]Bad eraseblock 1702 at 0x00000d4c0000
[15:10:01]Creating 4 MTD partitions on "NAND":
[15:10:01]0x000000000000-0x000000040000 : "bootloader"
[15:10:01]0x000000040000-0x000000060000 : "params"
[15:10:01]0x000000060000-0x000000460000 : "kernel"
[15:10:01]0x000000460000-0x000010000000 : "rootfs"
[15:10:01]dm9000 Ethernet Driver, V1.31
[15:10:01]ohci_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver
[15:10:01]s3c2410-ohci s3c2410-ohci: S3C24XX OHCI
[15:10:01]s3c2410-ohci s3c2410-ohci: new USB bus registered, assigned bus number 1
[15:10:01]s3c2410-ohci s3c2410-ohci: irq 42, io mem 0x49000000
[15:10:01]hub 1-0:1.0: USB hub found
[15:10:01]hub 1-0:1.0: 2 ports detected
[15:10:01]mousedev: PS/2 mouse device common for all mice
[15:10:01]s3c2410_wdt: S3C2410 Watchdog Timer, (c) 2004 Simtec Electronics
[15:10:01]s3c2410-wdt s3c2410-wdt: watchdog inactive, reset disabled, irq disabled
[15:10:01]TCP: cubic registered
[15:10:01]NET: Registered protocol family 17
[15:10:01]drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
[15:10:01]ALSA device list:
[15:10:01] No soundcards found.
[15:10:01]yaffs: dev is 32505859 name is "mtdblock3" rw
[15:10:01]yaffs: passed flags ""
[15:10:01]VFS: Mounted root (yaffs2 filesystem) on device 31:3.
[15:10:01]Freeing init memory: 124K
[15:10:01]Unable to handle kernel paging request at virtual address 6f692d73
[15:10:01]pgd = c0004000
[15:10:01][6f692d73] *pgd=00000000
[15:10:01]Internal error: Oops: 3 [#1] ARM
[15:10:01]Modules linked in:
[15:10:01]CPU: 0 Not tainted (3.4.2 #2)
[15:10:01]PC is at yaffs_getxattr+0x28/0x98
[15:10:01]LR is at get_vfs_caps_from_disk+0x64/0x100
[15:10:01]pc : [<c0119e94>] lr : [<c0133b6c>] psr: 60000013
[15:10:01]sp : c381fe08 ip : c381fe30 fp : c381fe2c
[15:10:01]r10: c3401d18 r9 : c381c660 r8 : c03f9c74
[15:10:01]r7 : c381fe34 r6 : 00000014 r5 : 6f692d6b r4 : c34057c0
[15:10:01]r3 : 00000014 r2 : f0000010 r1 : c037f434 r0 : c3401d18
[15:10:01]Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel
[15:10:01]Control: c000717f Table: 30004000 DAC: 00000017
[15:10:01]Process swapper (pid: 1, stack limit = 0xc381e270)
[15:10:01]Stack: (0xc381fe08 to 0xc3820000)
[15:10:01]fe00: c34057c0 c3401d18 c381fe7c c3a1a7c0 c381e000 c381c660
[15:10:01]fe20: c381fe64 c381fe30 c0133b6c c0119e7c 00000000 c3802be0 00000000 c3a5a5f8
[15:10:01]fe40: c3a4bde0 00000000 00000000 c3a1a7c0 c381c120 000081ff c381fec4 c381fe68
[15:10:01]fe60: c0133c98 c0133b18 c3a5a5f8 c381c150 00000000 60000013 c381feb4 00000000
[15:10:01]fe80: 00000000 00000000 00000000 00000000 c040a4bc c3a4be14 c381feb4 c3a1a7c0
[15:10:01]fea0: c34057c0 000081ff c3a1a7c0 c03ecfb0 c381ff30 c03ecf28 c381feec c381fec8
[15:10:01]fec0: c008b804 c0133c18 c008a6d4 c02f4854 00000001 00000002 c381e000 c04a92a5
[15:10:01]fee0: c381ff2c c381fef0 c008c0d8 c008b75c c04098d4 00000000 c381ae84 00000000
[15:10:01]ff00: c00a0148 c04a92a5 c03ecf28 c03ecfb0 c381ff30 0000006b c03c2210 c03dc040
[15:10:01]ff20: c381ff9c c381ff30 c000bdfc c008be7c 00000000 00000000 00000000 00000000
[15:10:02]ff40: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
[15:10:02]ff60: 00000000 00000000 00000000 00000000 00000000 00000000 c03ecf28 c040a000
[15:10:02]ff80: 00000008 c040a000 0000006b c03c2210 c381ffb4 c381ffa0 c00087dc c000bdcc
[15:10:02]ffa0: c03e0d4c c03dc03c c381fff4 c381ffb8 c03c23f8 c00086e8 00000007 00000007
[15:10:02]ffc0: c03c2210 c03c2284 c001a3b8 00000000 c03c2284 c001a3b8 00000013 00000000
[15:10:02]ffe0: 00000000 00000000 00000000 c381fff8 c001a3b8 c03c2294 33cd3a09 f3cc3bc0
[15:10:02]Backtrace:
[15:10:02][<c0119e6c>] (yaffs_getxattr+0x0/0x98) from [<c0133b6c>] (get_vfs_caps_from_disk+0x64/0x100)
[15:10:02] r9:c381c660 r8:c381e000 r7:c3a1a7c0 r6:c381fe7c r5:c3401d18
[15:10:02]r4:c34057c0
[15:10:02][<c0133b08>] (get_vfs_caps_from_disk+0x0/0x100) from [<c0133c98>] (cap_bprm_set_creds+0x90/0x424)
[15:10:02] r6:000081ff r5:c381c120 r4:c3a1a7c0
[15:10:02][<c0133c08>] (cap_bprm_set_creds+0x0/0x424) from [<c008b804>] (prepare_binprm+0xb8/0x11c)
[15:10:02][<c008b74c>] (prepare_binprm+0x0/0x11c) from [<c008c0d8>] (do_execve+0x26c/0x378)
[15:10:02] r6:c04a92a5 r5:c381e000 r4:00000002
[15:10:02][<c008be6c>] (do_execve+0x0/0x378) from [<c000bdfc>] (kernel_execve+0x40/0x8c)
[15:10:02][<c000bdbc>] (kernel_execve+0x0/0x8c) from [<c00087dc>] (init_post+0x104/0x140)
[15:10:02] r9:c03c2210 r8:0000006b r7:c040a000 r6:00000008 r5:c040a000
[15:10:02]r4:c03ecf28
[15:10:02][<c00086d8>] (init_post+0x0/0x140) from [<c03c23f8>] (kernel_init+0x174/0x1c4)
[15:10:02] r5:c03dc03c r4:c03e0d4c
[15:10:02][<c03c2284>] (kernel_init+0x0/0x1c4) from [<c001a3b8>] (do_exit+0x0/0x76c)
[15:10:02]Code: e1a06003 e3120002 e5915134 1a00000f (e5954008)
[15:10:02]---[ end trace e57bb244bbe532f0 ]---
[15:10:02]Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b
[15:10:02]
出现内核崩溃的情况,定位
yaffs_getxattr
可知该错误位于fs\yaffs2\Yaffs_vfs.c文件中:
#ifdef YAFFS_NEW_XATTR
static ssize_t yaffs_getxattr(struct dentry * dentry, struct inode *inode,
const char *name, void *buff, size_t size)
{
#else
static ssize_t yaffs_getxattr(struct dentry * dentry, const char *name,
void *buff, size_t size)
对于#ifdef 后面的宏,只要前面有#define 过的话不管它是0还是1都将执行
static ssize_t yaffs_getxattr(struct dentry * dentry, struct inode *inode,
const char *name, void *buff, size_t size)
这样的函数的声明,而不会执行else分支的声明。
在本文件中查找可发现:
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,12,0))
#define YAFFS_NEW_PROCFS
#include <linux/seq_file.h>
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
#define PAGE_CACHE_SIZE PAGE_SIZE
#define PAGE_CACHE_SHIFT PAGE_SHIFT
#define Y_GET_DENTRY(f) ((f)->f_path.dentry)
#define page_cache_release put_page
#define YAFFS_NEW_XATTR 1
#define YAFFS_NEW_GET_LINK 1
#else
#define Y_GET_DENTRY(f) ((f)->f_dentry)
#define YAFFS_NEW_XATTR 0
#define YAFFS_NEW_GET_LINK 0
#endif
内核版本大于3.12时,该宏定义为1,否则定义为0,无论是0还是1,该宏
YAFFS_NEW_XATTR
都是定义过的,函数yaffs_getxattr函数都将被声明为5个参数的类型。
而对于调用到yaffs_getxattr的结构体inode_operations:
static const struct inode_operations yaffs_file_inode_operations = {
.setattr = yaffs_setattr,
#ifdef YAFFS_USE_XATTR
.setxattr = yaffs_setxattr,
.getxattr = yaffs_getxattr,
.removexattr = yaffs_removexattr,
#endif
.listxattr = yaffs_listxattr,
};
该结构体的定义为:
struct inode_operations {
struct dentry * (*lookup) (struct inode *,struct dentry *, struct nameidata *);
void * (*follow_link) (struct dentry *, struct nameidata *);
int (*permission) (struct inode *, int);
struct posix_acl * (*get_acl)(struct inode *, int);
int (*readlink) (struct dentry *, char __user *,int);
void (*put_link) (struct dentry *, struct nameidata *, void *);
int (*create) (struct inode *,struct dentry *,umode_t,struct nameidata *);
int (*link) (struct dentry *,struct inode *,struct dentry *);
int (*unlink) (struct inode *,struct dentry *);
int (*symlink) (struct inode *,struct dentry *,const char *);
int (*mkdir) (struct inode *,struct dentry *,umode_t);
int (*rmdir) (struct inode *,struct dentry *);
int (*mknod) (struct inode *,struct dentry *,umode_t,dev_t);
int (*rename) (struct inode *, struct dentry *,
struct inode *, struct dentry *);
void (*truncate) (struct inode *);
int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);//函数声明为4个参数类型
ssize_t (*listxattr) (struct dentry *, char *, size_t);
int (*removexattr) (struct dentry *, const char *);
void (*truncate_range)(struct inode *, loff_t, loff_t);
int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
u64 len);
} ____cacheline_aligned;
故参数类型不一致会产生前面所说的wanning提示,到实际调用的时候可能就会产生致命的错误,故在此做以下的修改即可:
diff -urN compare-linux-3.4.2/linux-3.4.2/fs/yaffs2/yaffs_guts.c linux-3.4.2/fs/yaffs2/yaffs_guts.c
--- compare-linux-3.4.2/linux-3.4.2/fs/yaffs2/yaffs_guts.c 2018-03-03 09:13:13.514203584 +0800
+++ linux-3.4.2/fs/yaffs2/yaffs_guts.c 2018-03-02 16:11:55.347615000 +0800
@@ -4526,7 +4526,8 @@
} else if (obj->short_name[0]) {
strcpy(name, obj->short_name);
} else if (obj->hdr_chunk > 0) {
- int result;
+ //int result;//提示未初始化,提供个初始值即可,不加也行
+ int result=YAFFS_FAIL;
u8 *buffer = yaffs_get_temp_buffer(obj->my_dev);
struct yaffs_obj_hdr *oh = (struct yaffs_obj_hdr *)buffer;
diff -urN compare-linux-3.4.2/linux-3.4.2/fs/yaffs2/yaffs_vfs.c linux-3.4.2/fs/yaffs2/yaffs_vfs.c
--- compare-linux-3.4.2/linux-3.4.2/fs/yaffs2/yaffs_vfs.c 2018-03-03 09:13:13.778203584 +0800
+++ linux-3.4.2/fs/yaffs2/yaffs_vfs.c 2018-03-02 16:10:51.495705001 +0800
@@ -974,7 +974,8 @@
return error;
}
-#ifdef YAFFS_NEW_XATTR
+//#ifdef YAFFS_NEW_XATTR
+#if (YAFFS_NEW_XATTR > 0)
static ssize_t yaffs_getxattr(struct dentry * dentry, struct inode *inode,
const char *name, void *buff, size_t size)
{
总结:注意看编译过程的提示,不要对源码恐慌,理智分析。
修改上述错误之后,即可看到亲切的
Please press Enter to activate this console.