Chinaunix首页 | 论坛 | 博客
  • 博客访问: 674312
  • 博文数量: 118
  • 博客积分: 7172
  • 博客等级: 少将
  • 技术积分: 1799
  • 用 户 组: 普通用户
  • 注册时间: 2007-12-12 13:33
文章分类

全部博文(118)

文章存档

2012年(5)

2011年(12)

2010年(18)

2009年(36)

2008年(47)

我的朋友

分类: LINUX

2010-04-16 13:39:27

14. 内核加载地址和start参数问题
   从上面的分析, 知道内核被加载到0x30400 0000处, 这个其实是zImage的加载地址, 就是说内核解压缩程序的运行地址. 还有一个问题,我们的内核一直是little endian 的. arm-linux-objdump下就知道. 
   一个问题是Big-endian的内核如何run, 另一个是解压缩程序的运行地址是随意的吗?

  从monitor看, 这个环境一直在little endian运行... (big endian 实验也另作研究吧)

  能否加载到任意合理地址(至少有ram吧,呵呵), 试验一下即可. 结果证明是可以的, 当然应该行,因为zImage已经支持PIC代码,并且可以配置成在纯ROM环境下运行(那就得烧到到固定地址了). 

研究下zImage都包含什么东西,这个先从arch/arm/boot/Makefile看看吧:

$(obj)/compressed/vmlinux: $(obj)/Image FORCE
    $(Q)$(MAKE) $(build)=$(obj)/compressed $@

$(obj)/zImage:    $(obj)/compressed/vmlinux FORCE  #zImage 包含解压缩头的Image
    $(call if_changed,objcopy)
    @echo '  Kernel: $@ is ready'

.......
$(obj)/uImage:    $(obj)/zImage FORCE      # 
U-boot image
    $(call if_changed,uimage)
    @echo '  Image $@ is ready'

$(obj)/bootp/bootp: $(obj)/zImage initrd FORCE  包含bootp目录的image bootpImage, 如要initrd,这个平台不支持,所以加载    
    $(Q)$(MAKE) $(build)=$(obj)/bootp $@           
RamDisk 是monitor的事情了
    @:

$(obj)/bootpImage: $(obj)/bootp/bootp FORCE   #包含bootp目录的image bootpImage
    $(call if_changed,objcopy)
    @echo '  Kernel: $@ is ready'

  
内核解压缩和PIC (position independent code)
arch/arm/boot/compressed/Makefile

#
# We now have a PIC decompressor implementation.  Decompressors running
# from RAM should not define ZTEXTADDR.  Decompressors running directly
# from ROM or Flash must define ZTEXTADDR (preferably via the config)
# FIXME: Previous assignment to ztextaddr-y is lost here. See SHARK

ifeq ($(CONFIG_ZBOOT_ROM),y)  #
从boot ROM运行时需要配置一个固定地址,还有BSS的地址
ZTEXTADDR    := $(CONFIG_ZBOOT_ROM_TEXT)
ZBSSADDR    := $(CONFIG_ZBOOT_ROM_BSS)
else
ZTEXTADDR    := 0            #一般情况下,就是0, 是pic代码加上'手工'重定位,加载到任意地址
ZBSSADDR    := ALIGN(4)
endif

SEDFLAGS    = s/TEXT_START/$(ZTEXTADDR)/;s/BSS_START/$(ZBSSADDR)/   
#把
vmlinux.lds.in 中TEXT_START换成配置的地址(主要针对ZBOOT_ROM)

targets       := vmlinux vmlinux.lds piggy.gz piggy.o font.o font.c 
         head.o misc.o $(OBJS)
EXTRA_CFLAGS  := -fpic -fno-builtin
EXTRA_AFLAGS  :=
.............
# Don't allow any static data in misc.o, which
# would otherwise mess up our GOT table
CFLAGS_misc.o := -Dstatic=

$(obj)/vmlinux: $(obj)/vmlinux.lds $(obj)/$(HEAD) $(obj)/piggy.o 
         $(addprefix $(obj)/, $(OBJS)) FORCE
    $(call if_changed,ld)
    @:

$(obj)/piggy.gz: $(obj)/../Image FORCE  #piggy.gz 是压缩后的内核,见piggy.S
    $(call if_changed,gzip)

$(obj)/piggy.o:  $(obj)/piggy.gz FORCE

CFLAGS_font.o := -Dstatic=

$(obj)/font.c: $(FONTC)
    $(call cmd,shipped)

$(obj)/vmlinux.lds: $(obj)/vmlinux.lds.in arch/arm/boot/Makefile .config
    
@sed "$(SEDFLAGS)" < $< > $@

$(obj)/misc.o: $(obj)/misc.c include/asm/arch/uncompress.h lib/inflate.c

解压缩的pic技术以后再研究吧,挺多的.这里就是增强下信心吧.  知道可以加载到任意地址,呵呵. 下面看看decompress的入口函数start的参数问题:
arch/arm/boot/compressed/head.S
/*
 * sort out different calling conventions
 */
        .align
start:
        .type    start,#function
        .rept    8
        mov    r0, r0
        .endr

        b    1f
        .word    0x016f2818     &nb sp;  @ Magic numbers to help the loader
        .word    start            @ absolute load/run zImage address
        .word    _edata            @ zImage end address
1:        mov    r7, r1            
@ save architecture ID
        mov    r8, r2            @ save atags pointer

从这里看出, r1 存放的是architectureID, r2存放 atags 指针. 寄存器传递参数, 加上没有用的r0, 应该是这样一个函数:

void   start(0, archID, *atags)
其实,在arch/arm/kernel/head.S中有关于参数的一段详细的注释,看看就明白了:
/*
 * Kernel startup entry point.
 * ---------------------------
 *
 * 
This is normally called from the decompressor code.  The requirements
 * 
are: MMU = off, D-cache = off, I-cache = dont care, r0 = 0,
 * r1 = machine nr, r2 = atags pointer.
 *
 * This code is mostly position independent, so if you link the kernel at
 * 0xc0008000, you call this at __pa(0xc0008000).
 *
 * 
See linux/arch/arm/tools/mach-types for the complete list of machine
 * numbers for r1.

 *
 * We're trying to keep crap to a minimum; DO NOT add any machine specific
 * crap here - that's what the boot loader (or in extreme, well justified
 * circumstances, zImage) is for.
 */
找到mach-type是:
s3c2440            ARCH_S3C2440        S3C2440            362
不过通过实验, 我们的机器看来是SMDK兼容了,machine 参数必须传递193: SMDK2410 这个才行,而cpu类型则是自动侦测的,呵呵.

对应kernel的参数和decompressed一样:

void (*theKernel)(int zero, int arch, uint params);

另:试了试big endian,发现现在linux kernel对s3c的系统还不支持big模式.make config也无此选项.

--------------------------------------------------------------------------------
15. 
initrd : initial ram disk load process
     让我们从新审视所得到的内核console的输出(见上文),看看需要做的东西, 先来关注最后几行的输出信息,内核相关代码是:

start_kernel->rest_init->kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);->
static int __init 
kernel_init(void * unused)
{
..........
    /*
     * check if there is an early userspace init.  If yes, let it do all
     * the work
     */

    if (!ramdisk_execute_command)  /*由内核命令行参数 rdinit= 来控制,我们没有指定 (搜索就知道是rdinit=来控制了...)*/
        ramdisk_execute_command = "/init";

    if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
        ramdisk_execute_command = NULL;
        
prepare_namespace();
    }
 .........
}

内核中有各种__setup宏定义的内核参数, 其前面的字符串是内核命令行, 其后的函数是这个命令行的处理函数,相关的宏定义在init.h中.grep下,很快有结果. 详细讨论先放一放. 
void __init 
prepare_namespace(void)
{
.............
    if (saved_root_name[0]) {
        root_device_name = 
saved_root_name; /*这个就是由 root=/dev/ram传递的内核参数,稍作搜索即知*/
        if (!strncmp(root_device_name, "mtd", 3)) { /*我们当然不是这个*/
          .............
        }
        
ROOT_DEV = name_to_dev_t(root_device_name); /*/dev/ram 解析出来的设备是 ROOT_DEV= root_RAM0(1,0)*/
        if (strncmp(root_device_name, "/dev/", 5) == 0)
            
root_device_name += 5; /* root_dev_name = "ram" */
    }

    if (initrd_load()) /*  CONFIG_BLK_DEV_INITRD 之后才能使用initrd,我们的.config是有的*/
        goto out;
    ......
    
mount_root();
out:
    sys_mount(".", "/", NULL, MS_MOVE, NULL);  /*  
/root 如何成为根, 何以叫mount root,原来并不是加载 "/"*/
    sys_chroot(".");
    security_sb_post_mountroot();
}

int __init initrd_load(void)
{
    if (
mount_initrd) { /*只有配置了内核命令行: noinitrd才为0, 我们当然没有'自杀'了*/
        create_dev("/dev/ram", Root_RAM0);  /*创建设备先...*/
        /*
         * Load the initrd data into /dev/ram0. Execute it as initrd
         * unless /dev/ram0 is supposed to be our actual root device,
         * in that case the ram disk is just set up here, and gets
         * mounted in the normal path.
         */
        if (
rd_load_image("/initrd.image") && ROOT_DEV != Root_RAM0) { /*下面看看/initrd.image啥时候创建的*/
            sys_unlink("/initrd.image");
            handle_initrd();
            return 1;
        }
    }
    sys_unlink("/initrd.image");
    return 0;
}

从我们配置的参数是Root_RAM0, 最后 void __init prepare_namespace(void)会调用mount_root:

void __init mount_root(void)
{
#ifdef 
CONFIG_ROOT_NFS
 ...
#endif
#ifdef 
CONFIG_BLK_DEV_FD
   ....
#endif
#ifdef 
CONFIG_BLOCK
    create_dev("/dev/root", 
ROOT_DEV);
    mount_block_root("/dev/root", 
root_mountflags); /*有默认值 MS_RDONLY | MS_SILENT*/
#endif
}

void __init 
mount_block_root(char *name, int flags)
{
    get_fs_names(fs_names); /*
所有已经安装的文件系统的名字列表*/
retry:
    for (p = fs_names; *p; p += strlen(p)+1) { /*
p代表fs type, 这里name 是/dev/root,就是Root_RAM0*/
        int err = do_mount_root(name, p, flags, 
root_mount_data); /*(dev,type,mntflags,(rootflags=,给具体文件系统的参数) )*/
        .......
        /*
如果失败了,下面的信息倒是没有显示出来....*/
        printk("VFS: Cannot open root device "%s" or %s ",
                root_device_name, b);
        printk("Please append a correct "root=" boot option; here are the available partitions: ");

        printk_all_partitions();
        panic("VFS: Unable to mount root fs on %s", b);
    }

    printk("List of all partitions: ");
    
printk_all_partitions();
    printk("No filesystem could mount root, tried: "); /*
列出曾经尝试的文件系统类型*/
    for (p = fs_names; *p; p += strlen(p)+1)
        printk(" %s", p);
    printk(" ");
.......
    panic("VFS: Unable to mount root fs on %s", b); /*
知名panic*/
...
}

好了上面的函数就是知名的panic. 这个过程就是将文件/initrd.image 拷贝到Root_RAM0设备内, 然后创建设备文件/dev/root(这个个文件就是为了fs的接口函数准备的),然后将 /dev/root 安装到/root, 最后升级/root到文件系统根目录 '/'.

遇到这个panic从代码上看,是do_mount_root在尝试用各种文件系统来解析/dev/root后竭尽失败.无奈之下,panic的.原因可就多了,比如config的时候没有选上ramdisk支持(设备层), 或者ramdisk中的文件系统内核不支持(文件系统层), 再或者initrd的加载出了问题(无论是boot loader 还是内核创建"/initrd.image", 最后参数传递错误也不成. 经过仔细检查,内核配置和参数传递应该没有啥问题. 这里好多内核的信息没有打印出来,详细的错误也就被隐蔽了. 
  为了验证ramdisk是否正确加载, 在
rd_load_image("/initrd.image") 里面加了不少调试信息,结果发现, 根本没有/initrd.image这个文件,在这个函数打开这个文件的时候出错了, 这证明这个文件创建失败了. 原因也很多,不过还是先扫一眼这个文件在什么地方创建.一搜,在这个函数里呢:

static int __init populate_rootfs(void) 这是一个init函数,内核悄悄的运行了他.... (运行的地方好找,不提).
static int __init populate_rootfs(void)
{
 ...  /*
解压缩先略过不看...*/
    if (
initrd_start) { /*这个就是内核命令行传递进来的值...., 汗...monitor里这个值是0, 显然是不对的啊*/
        /* ...创建 initrd.image 这个文件*/
        fd = sys_open("/initrd.image", 
O_WRONLY|O_CREAT, 0700);
      .......
}

好了一个问题出来了, 改吧, 去monitor的参数里修改一番,也犯了不少错误: 
1) 第一个就是initrd的初始地址不能为0...,

2) 再有就是有个地方出错比如我设置initrd初始地址0x1000(随意值), 大小是0x1000(随意值,不设置长度monitor不加载ramdisk,只对此monitor有效). 这个地址有傻问题? 看看输出:
Memory policy: ECC disabled, Data cache writeback
initrd (0x00000000 - 0x000003e8) extends beyond physical memory - disabling initrd
CPU S3C2440A (id 0x32440001)
这里又跳出个地方和initrd有关, 位置在bootmem初始化中:(ft...)
arch/arm/mm/init.c
static int __init 
check_initrd(struct meminfo *mi)
{
.......
    if (
phys_initrd_size) {/*最初传递的initrd start 和size都是0, 我ft.... */
         for (i = 0; i < mi->nr_banks; i++) {
             ...........
         }

    if (initrd_node == -1) {
        printk(KERN_ERR "initrd (0x%08lx - 0x%08lx) extends beyond "
               "physical memory - disabling initrd ",
               phys_initrd_start, end);
        phys_initrd_start = phys_initrd_size = 0;
    }
..........
}
没有仔细探究这个bank是个什么意思(估计就是S3C2440 cpu里对内存bank的划分吧),但是这个警告信息提醒了我.超出物理内存? 不一定是地址太大,呵呵,因为啊, ram物理地址并不是从0开始的,启动的时候是S3C2440 自己吧nand读到了地址0开始的一段内部ram中.....所以,吧initrd start地址和size设置成一个在RAM地址范围内的一段地址里. 重启,这下,果然不同了........
     出现的信息还是不能加载root文件系统,但是initrd加载成功了, 即ramdisk已经包含了initrd.image, "
/initrd.image"文件也已经创建成功了. 但是出现RAMDISK: image too big! (2078xx/4096) ,相关函数是

int __init rd_load_image(char *from) /*从/initrd.image 写入/dev/ram设备*/
{
......
     /*
nblocks是从ramdisk image中根据文件系统magic猜测的block数(identify_ramdisk_image),
      *rd_blocks是从
/dev/ram设备中读出的数值,ramdisk大小是4096K size ,1024 blocksize,可以配置
      */
    if (nblocks > rd_blocks) { /*
这个信息是发现加载的initrd image大小大于ram disk的大小,加载失败*/
        printk("RAMDISK: image too big! (%dKiB/%ldKiB) ",
               nblocks, rd_blocks);
        goto done;
    }
....
}
另外,建议调试阶段把kernel consolelog 设置成verbose,就是在setup_arch的最前端,调用下面函数:
    console_verbose();
这样一些提示性和continue性质的信息能够显示出来方便调试.

  这个原因是什么? 根据调试信息打印出来信息, identify_ramdisk_image:RAMDISK: cramfs filesystem found at block 0
显然是发现了一个cramfs,但是不知到是什么原因. 呵呵,秘密是我还没有烧一个initrd进去呢,用的是现有的, 其大小和格式都是未知的.这样当然累了,要知道原因就太难(?), 所以要自己制作一个....

--------------------------------------------------------------------------------
16. 
制作ramfs

为了测试,仅制作文件系统..步骤如下:  
RDSIZE=1024  
BLKSIZE=1024
# 为了测试,越小越好,创建一个1M 的ram disk,这样下载快(现在我只有串口)
dd if=/dev/zero of=ramdisk.img bs=$BLKSIZE count=$RDSIZE
#在其上制作ext2文件系统
/sbin/mke2fs -F -m 0 -b $BLKSIZE ramdisk.img $RDSIZE     
-F       强制运行,不管是否是块设备/或者已经安装
-m 0     设置预留块数量的百分比, 我们可不能浪费,所以一个都不保留....呵呵.
-b 1024  一个block 1k
下载,运行,呵呵又出错了:
try load ram disk /*这是自己加的调试信息*/
RAMDISK: ext2 filesystem found at block 0   /*我们制作的是ext2文件系统,这里也认出了*/
RAMDISK: Loading 4000KiB [1 disk] into ram disk... done. /*这里看出initrd真是加载成功了,到了ramdisk0中*/
load image ret 1   /*这是自己加的调试信息, mount失败*/    
       原因很明显,我们根本没有编译ext2文件系统支持, 重新配置编译,运行.呵呵根文件系统安装真的成功了.不过,问题还没有完:
VFS: Mounted root (ext2 filesystem).
Freeing init memory: 92K
Warning: unable to open an initial console.
Failed to execute /linuxrc.  Attempting defaults...
Kernel panic - not syncing: No init found.  Try passing init= option to kernel.
这个嘛,嘿嘿,我们的文件系统上啥都没有, 得搞个什么东西上去才行啊. 
--------------------------------------------------------------------------------

16.1 initrd "hello world"   
    也试了直接编译busybox,可是看起来busybox启动了,但是没有任何输出.查busybox的说明,busybox建议最好自己用cross toolchain搞个hello world试试,看看你能不能运行,不行的话就别搞busybox了,肯定不行啦.
   故而,写hello world一个(好久不hello world了):   
arm-linux-gcc -static -o test test.c   
arm-linux-objcopy -S test test_strip  [
这个去掉大部分没有用的段,大大减小bin的大小]   
    然后用arm-linux-readelf -A test 看看. (aeabi)   在rootfs上(ramdisk.img)建立/dev和必要的设备文件:   
mount -t ext2 ramdisk.img /mnt/initrd -o loop   
mkdir dev   
cp -a /dev/null dev   
cp -a /dev/console dev   
cp /cross/src/linux2.6.24.4/test_strip linuxrc   [我们的hello world就是linuxrc,呵呵]   
sync   
umount /mnt/initrd      
gzip -9 ramdisk.img 
     下载, 启动.... 没有看到我熟悉的hello world
VFS: Mounted root (ext2 filesystem).
Freeing init memory: 92K
selected clock c01adf24 (pclk) quot 26, calc 115740
     google下,发现自己几乎犯过了所有的毛病,先是内核并不支持eabi串口无输出,就编译成支持eabi的内核,结果一样不幸.再google,发现float point emulation必须选一,我没选,选上重来. 最终float point终于解决了这个问题.内核中只能使用浮点模拟,运行大部分的 binaries 都需要浮点支持.
   最后hello world终于搞定了. (经测试,没有eabi支持的内核照样可以hello world,以后再研究吧]
VFS: Mounted root (ext2 filesystem).
Freeing init memory: 92K
selected clock c01adf24 (pclk) quot 26, calc 115740
hello world  [这就是我们期待的输出...]

--------------------------------------------------------------------------------

16.2 busy box
    先编译一个busybox用用,到   下载最新的1.9.2玩玩.
    配置的时候选上 don't use /usr,不然make install 就完蛋了
make ARCH=arm CROSS_COMPILE=arm-linux- allnoconfig
make ARCH=arm  CROSS_COMPILE=arm-linux- menuconfig  /*
只要ash mount echo ls cat ps dmsg sysctl, static 连接*/
make  ARCH=arm  CFLAGS="-I/cross/cross-arm/arm-linux/sys-include/" CROSS_COMPILE=arm-linux-
make  ARCH=arm  CFLAGS="-I/cross/cross-arm/arm-linux/sys-include/" CROSS_COMPILE=arm-linux- install
(需要把applets.c的警告去掉, glibc静态连接不好用,有bug,我们就试试,玩玩, 建议用ulibc,呵呵)然后就开始制作了:
把我们先前制作的ramdisk.img加载到临时目录
mount ramdisk.img /mnt/initrd -t ext2 -o loop=/dev/loop0
# busy box 为我们建立好了各种符号连接,copy即可
cp -rf  /cross/src/busybox-1.9.2/_install/*  .
我们的rootfs就有了 bin sbin 和linuxrc
然后在ramdisk上建立如下目录
mkdir dev
# 创建相应的设备文件
cp -a /dev/console dev
cp -a /dev/null dev
#cp -a /dev/ttyS0 dev   #没用s3c2410上串口设备是s3c2410_serial1
#cp -a /dev/ttyS1 dev   #
解除安装, 可以压缩的(俺的很小,不压缩也罢!)
umount /mnt/initrdgzip -9 ramdisk.img
#先搞这么多,先玩一把,下面是输出,爽啊
FS: Mounted root (ext2 filesystem).
Freeing init memory: 92K
selected clock c01a9df0 (pclk) quot 26, calc 115740
selected clock c01a9df0 (pclk) quot 26, calc 115740
init started: BusyBox v1.9.2 (2008-04-18 22:44:50 CST)
selected clock c01a9df0 (pclk) quot 26, calc 115740
command='reboot' action=32 tty=''
command='umount -a -r' actselected clock c01a9df0 (pclk) quot 26, calc 115740ion=64 tty=''
command='init' action=128 tty=''
command='-/bin/sh' action=4 tty=''
command='-/bin/sh' action=4 tty='/dev/tty2'
command='-/bin/sh' action=4 tty='/dev/tty3'
command='-/bin/sh' action=4 tty='/dev/tty4'
command='/etc/init.d/rcS' action=1 tty=''
starting pid 720, tty '': '/etc/init.d/rcS'
Cannot run '/etc/init.d/rcS': No such file or directory
waiting for enter to start '/bin/sh'(pid 721, tty '')
Please press Enter to activate this console. 
Can't open /dev/tty3: No such file or directory
Can't open /dev/tty4: No such file or directory
process '-/bin/sh' (pid 724) exited. Scheduling it for restart.
process '-/bin/sh' (pid 726) exited. Scheduling it for restart.
Can't open /dev/tty3: No such file or directory
Can't open /dev/tty4: No such file or directory(不断重复中,看看需要做的东西还多着呢,
不过ash已经启动了...ls可以工作的..呵呵)
这个事情有人报告是个bug:
 
关于这个问题的报告 既然如此,先升级的1.10.1看看, 测试结果:
1. applets.c的警告没有了
2. make ARCH=arm CROSS_COMPILE=arm-linux-  CFLAGS=-I/cross/cross-arm/arm-linux/sys-linux这次busybox选的东西比较多,弄了个2M的ramdisk, 压缩后399k. ...
问题一样地...,好了自己写linuxrc吧.
--------------------------------------------------------------------------------

16.3 为busybox 配置脚本
1) 先简单看看各种文件系统的作用吧:
tmpfs  :/dev/shm   #share mem对应的文件系统
devpts :/dev/pts   #目前最常见的 pseudo 终端(PTYs)实现方式
sysfs  :/sys       #sysfs 包含进程相关的proc fs,设备相关的devfs以及为终端相关的devpty fs的信息,是当前趋势, 
                     由内核内的kobj形成,udev严重依赖于sysf,能够在/dev目录下产生系统真正存在的设备,而不是一锅粥的方式
                      sysfs和udev配合,势必要击败devfs+devfsd(?)
udev   :           # 需要/etc/udev/rules.d 目录和一堆的配置规则
devfs   :/dev         #和devfsd配合使用, devfsd将会负责创建“旧类型”兼容性设备节点;在注册/注销设备时执行自动化操作;                      负责备份对根文件系统上某个目录的设备许可权和所有权的更改,以及其它更多功能
proc   :proc       # proc文件系统,不必多说

2) 
简单的inuxrc:
#!/bin/she
cho echo "Open ARM AKAE "
echo 
mount -t proc /proc /proc 
mount -t sysfs sysfs /sys
mount -t devpts devpts /dev/pts
echo "Start mdev..."
mdev -s                         /*mdev -s 把设备从sysfs 同步到/dev目录,需要要/etc/mdev.conf*/
init                            /*传递给脚本inittab...*/

3) /etc/inittab
s3c2410_serial1::respawn:-/bin/sh   #/*
注意s3c2410上串口的设备名称是/dev/s3c2410_serial[0..3]*/

4) /etc/mdev.conf
#空文件,有就行,用了在说吧

5) 启动信息
Open ARM akae
Start mdev...
selected clock c0239b70 (pclk) quot 26, calc 115740
init started: Busyselected clock c0239b70 (pclk) quot 26, calc 115740
Box v1.10.1 (2008-04-19 15:27:01 CST)
command='-/bin/sh ' action=2 tty='/dev/s3c2410_serial1'
starting pid 229, tty '/dev/s3c2410_serial1': '-/bin/sh '
BusyBox v1.10.1 (2008-04-19 15:27:01 CST) built-in shell (ash)
Enter 'help' for a list of built-in commands.
#

6) 
Trouble shoot
(1) 
/bin/sh: can't access tty; job control turned off
  busybox 通过系统控制台来做些工作, 如果我们的shell启动在 /dev/console  (5,1)上, tty_io.c 函数open中noctty就被设置成1,导致这个问题,具体原因还不知道.总之要启动在一个真实的串口就没有关系. 
  解决方法可以通过busybox的init指定shell的设备, 注意, S3C2410上, 串口1是
s3c2410_serial1.最终就是在etc/inittab中加入下面一句话就可以了:
s3c2410_serial1::respawn:-/bin/sh   #/*
注意s3c2410上串口的设备名称是/dev/s3c2410_serial[0..3]*/ 
(2)busybox的init脚本问题  no tty3 tty4 之类
  可以先启动mdev, (mdev -s), 然后运行init就可以了.
   就是让/dev/tty0-4 都存在即可.... (具体原因未知)
(3) 加载mtdblock3 的jffs2文件系统出现下述信息:
   jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x0001001c: 0x3c04
   建议:将此分区数据清除,更近一步,加载一个image到这个分区.
(4)下载了新内核,ramdisk找不到了
  runaddr 和 ramdisk距离太近, 内核解压缩后覆盖了ramdisk... ft
--------------------------------------------------------------------------------

阅读(1004) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~