CROSS_COMPILE :=/usr/local/arm/4.4.3/bin/arm-linux-
2, 修改机器码:要让bootload的机器码和内核的机器码一致(machine ID)
2、1 在u-boot代码(./board/samsung/smdk2416/smdk2416.c)中,赋值machine ID的代码如下:
这个宏的定义在:include/configs/smdk2416.h
2、2 在linux内核(./arch/arm/mach-s3c2416/mach-smdk2416.c)中,代码是这样:
4、1配置内核之前,先修改有些地方的Kconfig吧,以支持我们2416的板子
4、1、1 linux-2.6.35\arch\arm\mach-s3c2416\kconfig中增加:obj-$(CONFIG_S3C_DEV_USB_HOST) += dev-usb.o
等相应的宏打开
4、1、2 linux-2.6.35\arch\arm\plat-s3c24xx\kconfig中增加:
config MACH_SMDK
这个是使针对makefile 文件宏控制做相应的更改的:
4、2 配置内核
Kernel Features ---> //使用EABI工具链这两项是必须选择的
[*] Use the ARM EABI to compile the kernel
[*] Allow old ABI binaries to run with this kernel (EXPERIMENTAL) (NEW)
System Type --->(选板子)
S3C2410 Machines --->S3C2416 Machines --->
5,编译内核
#make zImage
编译完后,会在 arch/arm/boot 下生成zImage内核镜像文件
可以修改该目录下的 Makefile: 在第 57 行下面添加:
@cp –f arch/arm/boot/zImage zImage
@echo ` Kernel: $@ is ready`
下载到机子看看,内核起来了。到这里只是引导起来了。
6、内核分区,nandflash分区
6、1 修改:arch/arm/plat-s3c24xx/common-smdk.c 文件,在第 110 行:
/* NAND parititon from 2.4.18-swl5 */
static struct mtd_partition smdk_default_nand_part[] = {
[0] = {
.name = "2416_Boot",
.size = 0x00100000,
.offset = 0,
.mask_flags= MTD_CAP_NANDFLASH,
},
[1] = {
.name = "2416_kernel",
.offset = 0x00100000,
.size = 0x00800000,
.mask_flags= MTD_CAP_NANDFLASH,
},
.name = "2416_kernel",
.offset = 0x00900000,
.size = 0x00300000,
.mask_flags= MTD_CAP_NANDFLASH,
},
[3] = {
.name = "2416_rootfs",
.offset = 0x00c00000,
.size = MTDPART_OFS_APPEND,
}
};
然后修改NandFlash的读写匹配时间,修改common-smdk.c文件的刚刚修改后的大概140行左右的
smdk_nand_info结构体,修改内容如下:
staticstructs3c2410_platform_nandsmdk_nand_info={
.tacls =10,
.twrph0 =25,
.twrph1 =10,
.nr_sets =ARRAY_SIZE(smdk_nand_sets),
.sets =smdk_nand_sets,
};
6、2 然后修改“drivers/mtd/nand/s3c2410.c”文件的842行的NAND_ECC_SOFT改为NAND_ECC_NONE
将原来的内容改为如下所示
} else {
chip->ecc.mode = NAND_ECC_NONE; // NAND_ECC_SOFT
}
if (set->ecc_layout != NULL)
chip->ecc.layout = set->ecc_layout;
6、3 配置内核,支持 NandFlash
Device Drivers --->
<*> Memory Technology Device (MTD) support --->
[*] MTD partitioning support
<*> NAND Device Support --->
<*> NAND Flash support for Samsung S3C SoCs
[ ] Samsung S3C NAND driver debug
[ ] Samsung S3C NAND Hardware ECC //
{ }
};
6、5启动后若打印信息如下错误
7、jffs文件系统
7.1
具体的打印信息:http://bbs.csdn.net/topics/390537024
首先是解读表面上的含义,那就是找不到可执行文件 linuxrc 或者说是执行不了 。于是回头去看打印的信息,
VFS: Mounted root (jffs2 filesystem) on device 31:3.
Freeing init memory: 132K
可以看出文件系统有挂载上去,所以接下来就怀疑可能是文件系统出问题了。回头看文件系统:文件系统制作时用的交叉编译器和内核是一样的,而且在之前的内核2.6.21上面是正常跑起来的,根据这个我认为文件系统是没问题的,就怀疑是内核配置问题。然后在网上查一通,该支持额都配置了。还是不行:然后根据打印信息查找出是哪里打印出来的,在linux2.6.35/init/main.c 826行
/* This is a non __init function. Force it to be noinline otherwise gcc
* makes it inline to init() and it becomes part of init.text section
*/
static noinline int init_post(void)
__releases(kernel_lock)
{
/* need to finish all async __init code before freeing the memory */
async_synchronize_full();
free_initmem();
unlock_kernel();
mark_rodata_ro();
system_state = SYSTEM_RUNNING;
numa_default_policy();
current->signal->flags |= SIGNAL_UNKILLABLE;
if (ramdisk_execute_command) {
run_init_process(ramdisk_execute_command);
printk(KERN_WARNING "Failed to execute %s\n",
ramdisk_execute_command);
}
/*
* We try each of these until one succeeds.
*
* The Bourne shell can be used instead of init if we are
* trying to recover a really broken machine.
*/
if (execute_command) {
run_init_process(execute_command);
printk(KERN_WARNING "Failed to execute %s. Attempting "
"defaults...\n", execute_command);
}
run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");
panic("No init found. Try passing init= option to kernel. "
"See Linux Documentation/init.txt for guidance.");
}
由我们boot的启动参数可以看出execute_command值是/linuxrc,run_init_process(execute_command);这个函数如果可以执行那么就不会返回回来也就不会打印红色字体的信息了,这说明“run_init_process”这个函数执行有问题:我们来看看这个函数:
static void run_init_process(char *init_filename)
{
argv_init[0] = init_filename;
kernel_execve(init_filename, argv_init, envp_init);
}
再去看函数“kernel_execve”:在arch/arm/kernel/sys_arm.c
int kernel_execve(const char *filename, char *const argv[], char *const envp[])
{
struct pt_regs regs;
int ret;
memset(®s, 0, sizeof(struct pt_regs));
ret = do_execve((char *)filename, (char __user * __user *)argv,
(char __user * __user *)envp, ®s);
if (ret < 0)
goto out;
/*
* Save argc to the register structure for userspace.
*/
regs.ARM_r0 = ret;
/*
* We were successful. We won't be returning to our caller, but
* instead to user space by manipulating the kernel stack.
*/
asm( "add r0, %0, %1\n\t"
"mov r1, %2\n\t"
"mov r2, %3\n\t"
"bl memmove\n\t" /* copy regs to top of stack */
"mov r8, #0\n\t" /* not a syscall */
"mov r9, %0\n\t" /* thread structure */
"mov sp, r0\n\t" /* reposition stack pointer */
"b ret_to_user"
:
: "r" (current_thread_info()),
"Ir" (THREAD_START_SP - sizeof(regs)),
"r" (®s),
"Ir" (sizeof(regs))
: "r0", "r1", "r2", "r3", "ip", "lr", "memory");
out:
return ret;
}
EXPORT_SYMBOL(kernel_execve);
问题应该就出在这里头,但是这里有汇编,这下我头大了。不知道有谁能帮我探索一下,感激不尽啊!!!