<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > TE2410移植linux-2.6.14及調(diào)試過程總結(jié)(1)

          TE2410移植linux-2.6.14及調(diào)試過程總結(jié)(1)

          作者: 時間:2016-11-10 來源:網(wǎng)絡(luò) 收藏
          1.修改Makefile

          #cd linux-2.6.14

          本文引用地址:http://www.ex-cimer.com/article/201611/317262.htm

          #vi Makefile

          修改內(nèi)容如下

          ARCH =arm

          CROSS_COMPILE = arm-linux-

          下載交叉編譯器arm-linux-gcc3.4.1

          http://www.handhelds.org/download/projects/toolchain/arm-linux-gcc-3.4.1.tar.bz2

          解壓后,把交叉編譯工具鏈的路徑添加到環(huán)境變量中(修改/etc/bashrc文件)

          2.設(shè)置Nand Flash分區(qū)

          修改linux-2.6.14archarmmach-s3c2410devs.c

          (1)添加下列頭文件

          #include

          #include

          #include

          (2)添加NandFlash分區(qū)表

          static struct mtd_partition partition_info[]={

          {

          name:"bootloader",

          size:0x00020000,

          offset:0x0,

          },

          {

          name:"param",

          size:0x00010000,

          offset:0x00020000,

          },

          {

          name:"kernel",

          size:0x001c0000,

          offset:0x00030000,

          },

          {

          name:"rootfs",

          size:0x03e00000,

          offset:0x00200000,

          //mask_flags:MTD_WRITEABLE,

          }//,

          };

          其中

          name:代表分區(qū)名字
          size:代表flash分區(qū)大小(單位:字節(jié))
          offset:代表flash分區(qū)的起始地址(相對于0x0的偏移)

          (3)加入Nand Flash分區(qū)

          structs3c2410_nand_setnandset={

          nr_partitions:4,//5,

          partitions:partition_info,

          };

          nr_partitions:指明partition_info中定義的分區(qū)數(shù)目
          partitions:分區(qū)信息表

          (4)建立Nand Flash芯片支持

          struct s3c2410_platform_nandsuperlpplatform={

          tacls:0,

          twrph0:30,

          twrph1:0,

          sets:&nandset,

          nr_sets:1,

          };

          tacls, twrph0, twrph1的意思見S3C2410手冊的63,
          這3個值最后會被設(shè)置到NFCONF中,見S3C2410手冊66.
          sets:支持的分區(qū)集
          nr_sets:分區(qū)集的個數(shù)

          (5)加入Nand Flash芯片支持到Nand Flash驅(qū)動
          另外,還要修改此文件中的s3c_device_nand結(jié)構(gòu)體變量,添加對dev成員的賦值

          struct platform_device s3c_device_nand = {

          .name= "s3c2410-nand",

          .id= -1,

          .num_resources= ARRAY_SIZE(s3c_nand_resource),

          .resource= s3c_nand_resource,

          .dev={

          .platform_data =&superlpplatform

          }

          };

          name:設(shè)備名稱
          id:有效設(shè)備編號,如果只有唯一的一個設(shè)備為1,
          有多個設(shè)備從0開始計數(shù).
          num_resource:有幾個寄存器區(qū)
          resource:寄存器區(qū)數(shù)組首地址
          dev:支持的Nand Flash設(shè)備

          修改linux-2.6.14archarmmach-s3c2410mach-smdk2410.c

          static struct platform_device *smdk2410_devices[] __initdata = {

          &s3c_device_usb,

          &s3c_device_lcd,

          &s3c_device_wdt,

          &s3c_device_i2c,

          &s3c_device_iis,

          &s3c_device_nand,

          };

          (6)禁止Flash ECC校驗

          內(nèi)核都是通過UBOOT寫到Nand Flash的, UBOOT通過的軟件ECC算法產(chǎn)生ECC校驗碼,這與內(nèi)核校驗的ECC碼不一樣,內(nèi)核中的ECC碼是由S3C2410中Nand Flash控制器產(chǎn)生的.所以,我們在這里選擇禁止內(nèi)核ECC校驗.

          修改linux-2.6.14driversmtdnands3c2410.c

          找到函數(shù)s3c2410_nand_init_chip

          最后一條語句chip->eccmode= NAND_ECC_SOFT;

          改為chip->eccmode= NAND_ECC_NONE;

          3.配置內(nèi)核選項

          參考smdk2410開發(fā)板的配置文件,將其默認(rèn)的配置文件復(fù)制到內(nèi)核代碼的根目錄下,然后開始配置內(nèi)核

          #cd linux-2.6.14

          #cp arch/arm/configs/smdk2410_defconfig.config

          #make menuconfig

          注意:在每個選項前有個方括號,其中[*]/<*>表示該選項加入內(nèi)核編譯;[ ]/<>表示不選擇該選項;表示該選項作為模塊編譯,也就是說可以動態(tài)的加載和卸載該模塊.

          Loadable module support ->

          [*]Enable loadable module support #該選項的目的是使內(nèi)核支持可加載模塊,需要使用modprobe lsmod modinfo insmod rmmod等工具,所以必須選擇;

          [*]Module unloading #卸載模塊選項

          [*]Force module unloading#強制性卸載模塊選項,如用rmmod –f命令強制卸載;

          [ ]Module versioning support

          [ ]Source checksum for all modules

          [*]Automatic kernel module loading#內(nèi)核在任務(wù)中要使用一些被編譯為模塊的驅(qū)動或特性時,先使用modprobe命令來加載它,然后該選項自動調(diào)用modprobe加載需要的模塊,所以該選項一定要選擇.

          加入內(nèi)核對S3C2410 DMA(Direct Memory Access)的支持,配置如下:

          System Type ->

          [*]S3C2410 DMA support

          修改命令行參數(shù)

          Boot options ->

          Default kernel command string

          修改后內(nèi)容如下:

          noinitrd root=/dev/mtdblock3init=/linuxrc console=ttySAC0,115200 mem=64M

          或者

          noinitrd root=/dev/mtdblock/3init=/linuxrc console=ttySAC0,115200 mem=64M

          mtdblock3表示使用Flash的第4個分區(qū)(就是rootfs分區(qū)),console=ttySAC0表示kernel啟動期間的信息全部輸出到串口0上,115200表示波特率為115200,

          mem=64M表示內(nèi)存大小為64MB

          添加對浮點算法的支持

          Floating point emulation ->

          [*]NWFPE math emulation#支持NWFPE浮點數(shù),在許多情況下要使用,所以最好選上

          對MTD(Memory Technology Devices)設(shè)備(如Flash RAM等芯片)進(jìn)行配置,選擇配置如下

          Device Drivers->

          Memory Technology Devices(MTD)->

          [*]MTD partitioning support

          Device Drivers->

          Memory Technology Devices(MTD)->

          RAM/ROM/Flash chip drivers->

          <*>Detect flash chips by Common Flash Interface(CFI)probe

          <*>Detect non-CFI AMD/JEDEC-compatible flash chips

          <*>Support for Intel/Sharp flash chips

          <*>Support for AMD/Fujitsu flash chips

          <*>Support for ROM chips in bus mapping

          Device Drivers->

          Memory Technology Devices(MTD)->

          NAND Flash Device Drivers->

          <*>NAND Device Support

          <*>NAND Flash support for S3C2410/S3C2440 SoC

          為了要內(nèi)核支持devfs(Device Filesystem,設(shè)備文件系統(tǒng)),以及在啟動時能自動加載/dev為devfs,需要對文件系統(tǒng)進(jìn)行設(shè)置。

          File systems ->

          < >Second extended fs support#去除對ext2的支持

          Linux2.6.14 fs/Kconfig沒有支持devfs的選項(從2.6.13開始),所以make menuconfig時找不到相關(guān)菜單項

          從2.6.10的fs/Kconfig中copy幾項過來

          config DEVFS_FS

          bool "/dev file system support (OBSOLETE)"

          depends on EXPERIMENTAL

          help

          This is support for devfs, a virtual file system (like /proc) which

          provides the file system interface to device drivers, normally found

          in /dev. Devfs does not depend on major and minor number

          allocations. Device drivers register entries in /dev which then

          appear automatically, which means that the system administrator does

          not have to create character and block special device files in the

          /dev directory using the mknod command (or MAKEDEV script) anymore.

          This is work in progress. If you want to use this, you *must* read

          the material in , especially

          the file README there.

          Note that devfs no longer manages /dev/pts!If you are using UNIX98

          ptys, you will also need to mount the /dev/pts filesystem (devpts).

          Note that devfs has been obsoleted by udev,

          .

          It has been stripped down to a bare minimum and is only provided for

          legacy installations that use its naming scheme which is

          unfortunately different from the names normal Linux installations

          use.

          If unsure, say N.

          config DEVFS_MOUNT

          bool "Automatically mount at boot"

          depends on DEVFS_FS

          help

          This option appears if you have CONFIG_DEVFS_FS enabled. Setting

          this to Y will make the kernel automatically mount devfs onto /dev

          when the system is booted, before the init thread is started.

          You can override this with the "devfs=nomount" boot option.

          If unsure, say N.

          config DEVFS_DEBUG

          bool "Debug devfs"

          depends on DEVFS_FS

          help

          If you say Y here, then the /dev file system code will generate

          debugging messages. See the file

          for more

          details.

          If unsure, say N.

          File systems ->

          Pseudo filesystems ->

          [*]/proc file system support

          [*]/dev file system support(OBSOLETE)

          [*]Automatically mount at boot

          [*]Virtual memory file system support(former shm fs)

          Miscellaneous filesystems ->

          <*>Compressed ROM file system support(cramfs)

          Network File Systems ->

          <*>NFS file system support

          除此之外,還需要配置一下選項支持S3C2410 RTC,USB,MMC/SD卡驅(qū)動,具體選項如下:

          Device Drivers->

          Character devices->

          [*]Nonstandard serial port support

          [*]S3C2410 RTC Driver

          Device Drivers->

          USB Support->

          <*>Support for Host-side USB

          Device Drivers->

          MMC/SD Card Support

          <*>MMC Support

          <*>MMC block device driver

          調(diào)試過程中出現(xiàn)的問題及解決辦法

          1.Starting kernel ...就打住了

          應(yīng)該是從u-boot跳轉(zhuǎn)至內(nèi)核的地址不正確,我下載的加了0x40字節(jié)頭信息的內(nèi)核鏡像,下載到0x30008000,正確的跳轉(zhuǎn)地址應(yīng)該是0x30008040,在

          u-boot-1.1.3lib_armarmlinux.c的do_bootm_linux函數(shù)代碼如下:

          void do_bootm_linux (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[],ulong addr, ulong *len_ptr, int verify)

          {

          DECLARE_GLOBAL_DATA_PTR;

          ulong len = 0, checksum;

          ulong initrd_start, initrd_end;

          ulong data;

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

          image_header_t *hdr = &header;

          bd_t *bd = gd->bd;

          . . .

          theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);

          . . .

          /* we assume that the kernel is in place */

          printf ("nStarting kernel ...nn");

          #ifdef CONFIG_USB_DEVICE

          {

          extern void udc_disconnect (void);

          udc_disconnect ();

          }

          #endif

          cleanup_before_linux ();

          theKernel (0, bd->bi_arch_number, bd->bi_boot_params);

          }

          theKernel = (void (*)(int, int, uint))ntohl(hdr->ih_ep);

          typedef struct image_header {

          uint32_tih_magic;/* Image Header Magic Number*/

          uint32_tih_hcrc;/* Image Header CRC Checksum*/

          uint32_tih_time;/* Image Creation Timestamp*/

          uint32_tih_size;/* Image Data Size*/

          uint32_tih_load;/* DataLoadAddress*/

          uint32_tih_ep;/* Entry Point Address*/

          uint32_tih_dcrc;/* Image Data CRC Checksum*/

          uint8_tih_os;/* Operating System*/

          uint8_tih_arch;/* CPU architecture*/

          uint8_tih_type;/* Image Type*/

          uint8_tih_comp;/* Compression Type*/

          uint8_tih_name[IH_NMLEN];/* Image Name*/

          } image_header_t;

          可以看出跳轉(zhuǎn)地址是由image_header結(jié)構(gòu)體的ih_ep(Entry Point Address)成員來確定的,而ih_ep是由mkimage時自己填寫的,如下是我填充的mkimage參數(shù),其中的

          -e 0x30008000就是來填充ih_ep成員的.

          mkimage -A arm -O Linux -T kernel -C none -a 0x30008000-e 0x30008000-n Linux-2.6.14 -d zImage uImage

          顯然這個值應(yīng)該是0x30008040

          mkimage -A arm -O Linux -T kernel -C none -a 0x30008000-e 0x30008040-n Linux-2.6.14 -d zImage uImage

          修改后啟動信息如下

          ## Booting image at 30008000 ...

          Image Name:Linux-2.6.14

          Created:2008-07-148:59:37 UTC

          Image Type:ARM Linux Kernel Image (uncompressed)

          Data Size:1028136 Bytes = 1004 kB

          Load Address: 30008000

          Entry Point:30008040

          Verifying Checksum ... OK

          XIP Kernel Image ... OK

          commandline:noinitrd root=/dev/mtdblock3 init=/linuxrc console= ttySAC0,115200 mem=64M

          Starting kernel ...

          Uncompressing Linux.................................................................... done, booting the kernel.

          2.Starting kernel ...

          Uncompressing Linux............................................................

          ......... done, booting the kernel.

          Error: unrecognized/unsupported machine ID (r1 = 0x000000c2).

          Available machine support:

          ID (hex)NAME

          000000c1SMDK2410

          Please check your kernel config and/or bootloader.

          修改linux-2.6.14archarmkernelhead.S,如下,藍(lán)色字體為添加內(nèi)容

          ENTRY(stext)

          msrcpsr_c, #PSR_F_BIT | PSR_I_BIT | MODE_SVC @ ensure svc mode

          @ and irqs disabled

          bl__lookup_processor_type@ r5=procinfo r9=cpuid

          movsr10, r5@ invalid processor (r5=0)?

          beq__error_p@ yes, error p

          movr1, #0xc1@參考linux-2.6.14includeasm-armmach-types.h

          bl__lookup_machine_type@ r5=machinfo

          movsr8, r5@ invalid machine (r5=0)?

          beq__error_a@ yes, error a

          3.Starting kernel ...

          Uncompressing Linux.................................................

          ......... done, booting the kernel.

          然后就停止了

          查看commandline完全正確,從上面的打印信息可以看出,內(nèi)核已經(jīng)解壓成功了,這樣只能進(jìn)入內(nèi)核跟蹤調(diào)試了

          在內(nèi)核中arch/arm/kernel/debug.S中存在一個debug函數(shù)叫做printascii,使用方法如下:

          adr r0, str_p1
          bl printascii
          str_p1:.asciz"nError: unrecognized/unsupported process typen"

          用printascii在arch/arm/kernel/head.S里跟蹤調(diào)試,直到跳轉(zhuǎn)到start_kernel都沒有發(fā)現(xiàn)問題,查到printascii在進(jìn)入start_kernel之后也可以使用,說明如下:

          mmu已經(jīng)開啟后,系統(tǒng)中的物理地址都變成虛擬地址了,因此原來基于物理地址的調(diào)試方案將都會失敗,但可以使用printascii繼續(xù)調(diào)試,該調(diào)試功能同時支持物理地址與虛擬地址,并且提供了一個解決方案就是將printascii加入到printk的vsprintf()之里。

          修改linux-2.6.14kernelprintk.c,藍(lán)色字體為添加內(nèi)容

          extern void printascii(const char*);

          asmlinkage int vprintk(const char *fmt, va_list args)

          {

          unsigned long flags;

          int printed_len;

          char *p;

          static char printk_buf[1024];

          static int log_level_unknown = 1;

          preempt_disable();

          if (unlikely(oops_in_progress) && printk_cpu == smp_processor_id())

          zap_locks();

          spin_lock_irqsave(&logbuf_lock, flags);

          printk_cpu = smp_processor_id();

          /* Emit the output into the temporary buffer */

          printed_len = vscnprintf(printk_buf, sizeof(printk_buf), fmt, args);

          printascii(printk_buf);

          ...

          ...

          }

          修改后內(nèi)核啟動成功,超級終端出來一大堆打印信息

          ## Booting image at 30008000 ...

          Image Name:Linux-2.6.14

          Created:2008-07-148:59:37 UTC

          Image Type:ARM Linux Kernel Image (uncompressed)

          Data Size:1028136 Bytes = 1004 kB

          Load Address: 30008000

          Entry Point:30008040

          Verifying Checksum ... OK

          XIP Kernel Image ... OK

          Starting kernel ...

          Uncompressing Linux.................................................................... done, booting the kernel.

          <5>Linux version 2.6.14 (root@localhost.localdomain) (gcc version 3.4.1) #3 Mon Jul 14 04:59:17 EDT 2008

          CPU: ARM920Tid(wb) [41129200] revision 0 (ARMv4T)

          Machine: SMDK2410

          Memory policy: ECC disabled, Data cache writeback

          CPU S3C2410A (id 0x32410002)

          S3C2410: core 202.800 MHz, memory 101.400 MHz, peripheral 50.700 MHz

          <6>S3C2410 Clocks, (c) 2004 Simtec Electronics

          CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on

          <7>On node 0 totalpages: 16384

          <7>DMA zone: 16384 pages, LIFO batch:7

          <7>Normal zone: 0 pages, LIFO batch:1

          <7>HighMem zone: 0 pages, LIFO batch:1

          CPU0: D VIVT write-back cache

          CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets

          CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets

          Built 1 zonelists

          <5>Kernel command line: noinitrd root=/dev/mtdblock3 init=/linuxrcconsole= ttySAC0,115200 mem=64M

          irq: clearing subpending status 00000003

          PID hash table entries: 512 (order: 9, 8192 bytes)

          timer tcon=00500000, tcnt a509, tcfg 00000200,00000000, usec 00001e4c

          Console: colour dummy device 80x30

          Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)

          Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)

          <6>Memory: 64MB = 64MB total

          <5>Memory: 62592KB available (1708K code, 381K data, 92K init)

          <7>Calibrating delay loop... 101.17 BogoMIPS (lpj=252928)

          Mount-cache hash table entries: 512

          <6>CPU: Testing write buffer coherency: ok

          softlockup thread 0 started up.

          <6>NET: Registered protocol family 16

          S3C2410: Initialising architecture

          <6>usbcore: registered new driver usbfs

          <6>usbcore: registered new driver hub

          S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics

          DMA channel 0 at c4800000, irq 33

          DMA channel 1 at c4800040, irq 34

          DMA channel 2 at c4800080, irq 35

          DMA channel 3 at c48000c0, irq 36

          <4>NetWinder Floating Point Emulator V0.97 (double precision)

          Console: switching to colour frame buffer device 80x25

          <6>fb0: Virtual frame buffer device, using 1024K of video memory

          S3C2410 RTC, (c) 2004 Simtec Electronics

          <6>s3c2410_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2410

          <6>s3c2410_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2410

          <6>s3c2410_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2410

          <6>io scheduler noop registered

          <6>io scheduler anticipatory registered

          <6>io scheduler deadline registered

          <6>io scheduler cfq registered

          RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize

          S3C24XX NAND Driver, (c) 2004 Simtec Electronics

          <6>s3c2410-nand: mapped registers at c4980000

          <6>s3c2410-nand: timing: Tacls10ns, Twrph010ns, Twrph110ns

          <4>No NAND device found!!!

          <5>usbmon: debugfs is not available

          <6>mice: PS/2 mouse device common for all mice

          <6>NET: Registered protocol family 2

          IP route cache hash table entries: 1024 (order: 0, 4096 bytes)

          TCP established hash table entries: 4096 (order: 2, 16384 bytes)

          TCP bind hash table entries: 4096 (order: 2, 16384 bytes)

          <6>TCP: Hash tables configured (established 4096 bind 4096)

          <6>TCP reno registered

          <6>TCP bic registered

          <6>NET: Registered protocol family 1

          <3>Root-NFS: No NFS server available, giving up.

          <3>VFS: Unable to mount root fs via NFS, trying floppy.

          VFS: Cannot open root device "mtdblock3" or unknown-block(2,0)

          Please append a correct "root=" boot option

          <0>Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(2,0)

          那么就說明內(nèi)核沒有問題,而是commandline參數(shù)有問題,仔細(xì)看,才發(fā)現(xiàn)

          noinitrd root=/dev/mtdblock3 init=/linuxrcconsole= ttySAC0,115200 mem=

          64M

          console=之后多了一個空格,但是不確定是否是這個原因,重新設(shè)置bootargs參數(shù),去掉空格

          setenv bootargs noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttyS

          AC0,115200 mem=64M

          重新下載,啟動成功.

          在網(wǎng)上查到有說u-boot和內(nèi)核頻率不一致可能導(dǎo)致串口沒有打印信息,最好將u-boot的頻率設(shè)為200M,不過我試過了,202.800 MHz也沒有問題

          Uncompressing Linux............................................................ done, booting the kernel.

          Linux version 2.6.14 (root@localhost.localdomain) (gcc version 3.4.1) #3 Mon Jul 14 04:59:17 EDT 2008

          CPU: ARM920Tid(wb) [41129200] revision 0 (ARMv4T)

          Machine: SMDK2410

          Memory policy: ECC disabled, Data cache writeback

          CPU S3C2410A (id 0x32410002)

          S3C2410: core202.800 MHz, memory 101.400 MHz, peripheral 50.700 MHz

          Starting kernel ...

          Uncompressing Linux................................................................... done, booting the kernel.

          Linux version 2.6.14 (root@localhost.localdomain) (gcc version 3.4.1) #20 Sat Jul 5 10:01:30 EDT 2008

          CPU: ARM920Tid(wb) [41129200] revision 0 (ARMv4T)

          Machine: SMDK2410

          Memory policy: ECC disabled, Data cache writeback

          CPU S3C2410A (id 0x32410002)

          S3C2410: core200.000 MHz, memory 100.000 MHz, peripheral 50.000 MHz

          1.S3C24XX NAND Driver, (c) 2004 Simtec Electronics

          s3c2410-nand: mapped registers at c4980000

          s3c2410-nand: timing: Tacls 10ns, Twrph0 10ns, Twrph1 10ns

          No NAND device found!!!

          usbmon: debugfs is not available

          mice: PS/2 mouse device common for all mice

          NET: Registered protocol family 2

          IP route cache hash table entries: 1024 (order: 0, 4096 bytes)

          TCP established hash table entries: 4096 (order: 2, 16384 bytes)

          TCP bind hash table entries: 4096 (order: 2, 16384 bytes)

          TCP: Hash tables configured (established 4096 bind 4096)

          TCP reno registered

          TCP bic registered

          NET: Registered protocol family 1

          Root-NFS: No NFS server available, giving up.

          VFS: Unable to mount root fs via NFS, trying floppy.

          VFS:Cannot open root device "mtdblock3" or unknown-block(2,0)

          Please append a correct "root=" boot option

          Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(2,0)

          原因可能是一下幾點:

          (1)commandline中的root=/dev/mtdblock3表示rootfs在Flash的第4分區(qū),檢查確認(rèn)rootfs是否是Flash的第4分區(qū)(第一個分區(qū)號為0)

          (2)Flash的rootfs分區(qū)中沒有下載好的根文件系統(tǒng),確認(rèn)是否下載好根文件系統(tǒng)

          (3)Flash的驅(qū)動有問題,無法對Flash進(jìn)行讀寫

          我的NAND Flash分區(qū)如下:

          mtdpart info. (5 partitions)

          nameoffsetsizeflag

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

          vivi: 0x000000000x000200000128k

          param: 0x000200000x00010000064k

          kernel: 0x000300000x001c000001M+768k

          rootfs: 0x002000000x02000000032M

          user: 0x022000000x01e00000030M

          所以commandline中的mtdblock3沒有錯誤

          我已下載好根文件系統(tǒng)至rootfs分區(qū),再看看串口的打印信息,注意紅色的部分

          No NAND device found!!!

          有點奇怪,其實我不太相信linux的源代碼會有問題,就在根文件系統(tǒng)的加載這一步拖了好多天,一開始由于自己的疏忽,make menuconfig時把有些選項選成模塊了,也沒有搞清楚<*>和的差別,串口打印信息也是到這一步,但是沒有No NAND device found!!!提示,因為NAND Flash的驅(qū)動沒有編譯進(jìn)內(nèi)核.后來才發(fā)現(xiàn)make menuconfig配置時出了問題,修改后,發(fā)現(xiàn)是NAND Flash驅(qū)動有問題,進(jìn)入內(nèi)核跟蹤發(fā)現(xiàn)

          linux-2.6.14driversmtdnands3c2410.c中s3c2410_nand_init函數(shù)對NAND Flash初始化

          static int __init s3c2410_nand_init(void)

          {

          printk("S3C24XX NAND Driver, (c) 2004 Simtec Electronicsn");

          driver_register(&s3c2440_nand_driver);

          returndriver_register(&s3c2410_nand_driver);

          }

          static struct device_drivers3c2410_nand_driver= {

          .name= "s3c2410-nand",

          .bus= &platform_bus_type,

          .probe=s3c2410_nand_probe,

          .remove= s3c2410_nand_remove,

          };

          static ints3c2410_nand_probe(struct device *dev)

          {

          returns3c24xx_nand_probe(dev, 0);

          }

          static ints3c24xx_nand_probe(struct device *dev, int is_s3c2440)

          {

          struct platform_device *pdev = to_platform_device(dev);

          struct s3c2410_platform_nand *plat = to_nand_plat(dev);

          struct s3c2410_nand_info *info;

          struct s3c2410_nand_mtd *nmtd;

          struct s3c2410_nand_set *sets;

          struct resource *res;

          . . .

          for (setno = 0; setno < nr_sets; setno++, nmtd++) {

          pr_debug("initialising set %d (%p, info %p)n",

          setno, nmtd, info);

          s3c2410_nand_init_chip(info, nmtd, sets);

          nmtd->scan_res =nand_scan(&nmtd->mtd,

          (sets) ? sets->nr_chips : 1);

          if (nmtd->scan_res == 0) {

          s3c2410_nand_add_partition(info, nmtd, sets);

          }

          if (sets != NULL)

          sets++;

          }

          . . .

          }

          經(jīng)過串口打印出nmtd->scan_res的值為1,根據(jù)

          if (nmtd->scan_res == 0) {

          s3c2410_nand_add_partition(info, nmtd, sets);

          }

          來判斷,應(yīng)該返回0.

          進(jìn)入nand_scan

          int nand_scan (struct mtd_info *mtd, int maxchips)

          {

          int i, nand_maf_id, nand_dev_id, busw, maf_id;

          struct nand_chip *this = mtd->priv;

          . . .

          /* Select the device */

          this->select_chip(mtd, 0);

          /* Send the command for reading device ID */

          this->cmdfunc (mtd, NAND_CMD_READID, 0x00, -1);

          /* Read manufacturer and device IDs */

          nand_maf_id= this->read_byte(mtd);

          nand_dev_id= this->read_byte(mtd);

          . . .

          /* Print and store flash device information */

          for (i = 0; nand_flash_ids[i].name != NULL; i++) {

          if (nand_dev_id != nand_flash_ids[i].id)

          continue;

          if (!mtd->name) mtd->name = nand_flash_ids[i].name;

          this->chipsize = nand_flash_ids[i].chipsize << 20;

          . . .

          /* Try to identify manufacturer */

          for (maf_id = 0; nand_manuf_ids[maf_id].id != 0x0; maf_id++) {

          if (nand_manuf_ids[maf_id].id == nand_maf_id)

          break;

          }

          . . .

          printk (KERN_INFO "NAND device: Manufacturer ID:"

          " 0x%02x, Chip ID: 0x%02x (%s %s)n", nand_maf_id, nand_dev_id,

          nand_manuf_ids[maf_id].name , nand_flash_ids[i].name);

          break;

          }

          if (!nand_flash_ids[i].name) {

          printk (KERN_WARNING "No NAND device found!!!n");

          this->select_chip(mtd, -1);

          return 1;

          }

          . . .

          }

          根據(jù)上面的代碼可以看出沒有在nand_flash_ids數(shù)組中找到nand_dev_id匹配值,記得在u-boot中也有nand_probe函數(shù)檢測NAND Flash,打印出2個ID值如下

          NAND:Flash chip found:Manufacturer ID:0xEC, Chip ID:0x76

          Linux中nand_flash_ids和nand_manuf_ids數(shù)組內(nèi)容如下:

          /*

          *Chip ID list*

          *Name. ID code, pagesize, chipsize in MegaByte, eraseblock size,

          */

          struct nand_flash_dev nand_flash_ids[] = {

          {"NAND 1MiB 5V 8-bit",0x6e, 256, 1, 0x1000, 0},

          {"NAND 2MiB 5V 8-bit",0x64, 256, 2, 0x1000, 0},

          {"NAND 4MiB 5V 8-bit",0x6b, 512, 4, 0x2000, 0},

          {"NAND 1MiB 3,3V 8-bit",0xe8, 256, 1, 0x1000, 0},

          {"NAND 1MiB 3,3V 8-bit",0xec, 256, 1, 0x1000, 0},

          {"NAND 2MiB 3,3V 8-bit",0xea, 256, 2, 0x1000, 0},

          {"NAND 4MiB 3,3V 8-bit",0xd5, 512, 4, 0x2000, 0},

          {"NAND 4MiB 3,3V 8-bit",0xe3, 512, 4, 0x2000, 0},

          {"NAND 4MiB 3,3V 8-bit",0xe5, 512, 4, 0x2000, 0},

          . . .

          {"NAND 64MiB 3,3V 8-bit",0x76, 512, 64, 0x4000, 0},

          . . .

          {NULL,}

          };

          /*

          *Manufacturer ID list

          */

          struct nand_manufacturers nand_manuf_ids[] = {

          {NAND_MFR_TOSHIBA, "Toshiba"},

          {NAND_MFR_SAMSUNG, "Samsung"},

          {NAND_MFR_FUJITSU, "Fujitsu"},

          {NAND_MFR_NATIONAL, "National"},

          {NAND_MFR_RENESAS, "Renesas"},

          {NAND_MFR_STMICRO, "ST Micro"},

          {NAND_MFR_HYNIX, "Hynix"},

          {0x0, "Unknown"}

          };

          /*

          * NAND Flash Manufacturer ID Codes

          */

          #define NAND_MFR_TOSHIBA0x98

          #defineNAND_MFR_SAMSUNG0xec

          #define NAND_MFR_FUJITSU0x04

          #define NAND_MFR_NATIONAL0x8f

          #define NAND_MFR_RENESAS0x07

          #define NAND_MFR_STMICRO0x20

          #define NAND_MFR_HYNIX0xad

          這樣就說明nand_scan中讀取NAND Flash的id值是錯誤的,不是0xec和0x76,從串口打印出來的id值確實不正確,首先我的NAND Flash肯定正常工作,在u-boot中一直是好的,那么可能是Linux中對Flash讀寫的出問題了,懷疑是發(fā)出命令后的延時有問題,向NAND Flash發(fā)出讀取id命令后的延時太短,導(dǎo)致讀出來的值錯誤,nand_wait_ready這個就是延時等待命令執(zhí)行完成的函數(shù),經(jīng)過測試沒有問題,到這個時候,真有點崩潰了.然后估計是NAND Flash的NFCONF寄存器設(shè)置有問題, NFCONF寄存器在函數(shù)s3c2410_nand_inithw中初始化,s3c2410_nand_inithw中將NFCONF寄存器的值打印出來,如下:

          s3c2410-nand: mapped registers at c4980000

          s3c2410-nand: timing:Tacls10ns, Twrph010ns, Twrph110ns

          s3c2410-nand: NF_CONF is0x8000

          與u-boot中設(shè)置的NFCONF寄存器值比較發(fā)現(xiàn),不同的是TACLS TWRPH0 TWRPH1以及是否初始化ECC,nFCE的值

          U-boot中TACLS TWRPH0 TWRPH1值分別為0 4 2,初始化ECC, nFCE=1(inactive)

          Linux中TACLS TWRPH0 TWRPH1值分別為0 0 0,未初始化ECC, nFCE=0(active)

          應(yīng)該是TACLS TWRPH0 TWRPH1的問題,查看S3C2410 user manual和NAND Flash用戶手冊Samsung K9F1208U0M user manual,找到三張圖,如下:

          圖1 s3c2410 user manual, nand flash memory timing

          顯然s3c2410 user manual推薦值是TACLS=0 TWRPH0=1 TWRPH1=0

          TACLS:1個HCLK TWRPH0:2個HCLK TWRPH1:1個HCLK

          內(nèi)核的頻率為200MHZ,即FCLK=200MHZ,則HCLK=100MHZ(周期為10ns),所以

          TACLS:10ns TWRPH0:20ns TWRPH1:10ns

          圖2 NAND Flash(K9F1208U0M) user manual,Read and Write timing

          tCLS等價于圖1中的TACLS;tWP等價于圖1中的TWRPH0;tCLH等價于圖1中的TWRPH1

          圖3 NAND Flash(K9F1208U0M) user manual

          結(jié)合前3張圖,可以看出對NAND Flash(K9F1208U0M)進(jìn)行讀寫的順序要求為:

          TACLS <----------->tCLS,最小值為0ns

          TWRPH0<----------->tWP,最小值為25ns

          TWRPH1<----------->tCLH,最小值為10ns

          內(nèi)核的頻率為200MHZ,即FCLK=200MHZ,則HCLK=100MHZ(周期為10ns)

          TACLS=0,TWRPH0=2,TWRPH1=0即可滿足時序要求,此時

          TACLS:10nsTWRPH0:30nsTWRPH1:10ns

          現(xiàn)在再看看先前串口輸出的信息:

          s3c2410-nand: mapped registers at c4980000

          s3c2410-nand: timing:Tacls 10ns, Twrph0 10ns, Twrph1 10ns

          No NAND device found!!!

          很顯然Twrph0 10ns <25ns,原來如此!!!!

          不過我試了一下TACLS=0,TWRPH0=1,TWRPH1=0, TACLS:10nsTWRPH0:20nsTWRPH1:10ns,NAND Flash照樣正常工作.不知道為什么.

          現(xiàn)在要說明一下我是如何修改的, TACLSTWRPH0TWRPH1的值在linux-2.6.14archarmmach-s3c2410devs.c中已經(jīng)設(shè)置,代碼如下:

          struct s3c2410_platform_nandsuperlpplatform={

          tacls:0,

          twrph0:3,

          twrph1:0,

          sets:&nandset,

          nr_sets:1,

          };

          這里設(shè)置的值和上面的分析是一致的,應(yīng)該沒有問題,但是為什么打印出來的卻是

          s3c2410-nand: timing:Tacls 10ns, Twrph0 10ns, Twrph1 10ns

          s3c2410_nand_inithw函數(shù)對NFCONF寄存器初始化,代碼如下:

          static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,

          struct device *dev)

          {

          struct s3c2410_platform_nand *plat = to_nand_plat(dev);

          unsigned int tacls, twrph0, twrph1;

          unsigned long clkrate = clk_get_rate(info->clk);

          unsigned long cfg;

          /* calculate the timing information for the controller */

          if (plat != NULL) {

          tacls= s3c2410_nand_calc_rate(plat->tacls, clkrate, 4);

          twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8);

          twrph1 = s3c2410_nand_calc_rate(plat->twrph1, clkrate, 8);

          printk("plat->tacls:%dn",plat->tacls);

          printk("plat->twrph0:%dn",plat->twrph0);

          printk("plat->twrph1:%dn",plat->twrph1);

          printk("tacls:%dn",tacls);

          printk("twrph0:%dn",twrph0);

          printk("twrph1:%dn",twrph1);

          printk("clkrate:%dn",clkrate);

          tacls=1;

          twrph0 =2;

          twrph1 =1;

          } else {

          /* default timings */

          tacls = 4;

          twrph0 = 8;

          twrph1 = 8;

          }

          if (tacls < 0 || twrph0 < 0 || twrph1 < 0) {

          printk(KERN_ERR PFX "cannot get timings suitable for boardn");

          return -EINVAL;

          }

          printk(KERN_INFO PFX "timing: Tacls %ldns, Twrph0 %ldns, Twrph1 %ldnsn",

          to_ns(tacls, clkrate),

          to_ns(twrph0, clkrate),

          to_ns(twrph1, clkrate));

          if (!info->is_s3c2440) {

          cfg= S3C2410_NFCONF_EN;

          cfg |= S3C2410_NFCONF_TACLS(tacls-1);

          cfg |= S3C2410_NFCONF_TWRPH0(twrph0-1);

          cfg |= S3C2410_NFCONF_TWRPH1(twrph1-1);

          } else {

          cfg= S3C2440_NFCONF_TACLS(tacls-1);

          cfg|= S3C2440_NFCONF_TWRPH0(twrph0-1);

          cfg|= S3C2440_NFCONF_TWRPH1(twrph1-1);

          }

          pr_debug(PFX "NF_CONF is 0x%lxn", cfg);

          writel(cfg, info->regs + S3C2410_NFCONF);

          return 0;

          }

          我加了一點代碼將相關(guān)參數(shù)打印出來:

          plat->tacls:0

          plat->twrph0:3

          plat->twrph1:0

          tacls:1

          twrph0:1

          twrph1:1

          clkrate:100000000

          真是搞不懂plat->tacls, plat->twrph0, plat->twrph1的值和前面初始化的值是一樣的,但是經(jīng)過s3c2410_nand_calc_rate函數(shù)處理后就出問題了,正確的輸出值應(yīng)該是

          tacls:1twrph0:4twrph1:1

          算了,對tacls,twrph0,twrph1三個變量強制性賦值

          tacls=1;

          twrph0 =2;

          twrph1 =1;

          修改后NAND Flash可以正常工作了,啟動信息如下:

          Linux version 2.6.14 (root@localhost.localdomain) (gcc version 3.4.1) #7 Mon Jul 14 09:34:58 EDT 2008

          CPU: ARM920Tid(wb) [41129200] revision 0 (ARMv4T)

          Machine: SMDK2410

          Memory policy: ECC disabled, Data cache writeback

          CPU S3C2410A (id 0x32410002)

          S3C2410: core 200.000 MHz, memory 100.000 MHz, peripheral 50.000 MHz

          S3C2410 Clocks, (c) 2004 Simtec Electronics

          CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on

          CPU0: D VIVT write-back cache

          CPU0: I cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets

          CPU0: D cache: 16384 bytes, associativity 64, 32 byte lines, 8 sets

          Built 1 zonelists

          Kernel command line: noinitrd root=/dev/mtdblock3 init=/linuxrc console=ttySAC0,115200 mem=64M

          irq: clearing subpending status 00000003

          irq: clearing subpending status 00000002

          PID hash table entries: 512 (order: 9, 8192 bytes)

          timer tcon=00500000, tcnt a2c1, tcfg 00000200,00000000, usec 00001eb8

          Console: colour dummy device 80x30

          Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)

          Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)

          Memory: 64MB = 64MB total

          Memory: 62592KB available (1708K code, 381K data, 92K init)

          Mount-cache hash table entries: 512

          CPU: Testing write buffer coherency: ok

          softlockup thread 0 started up.

          NET: Registered protocol family 16

          S3C2410: Initialising architecture

          usbcore: registered new driver usbfs

          usbcore: registered new driver hub

          S3C2410 DMA Driver, (c) 2003-2004 Simtec Electronics

          DMA channel 0 at c4800000, irq 33

          DMA channel 1 at c4800040, irq 34

          DMA channel 2 at c4800080, irq 35

          DMA channel 3 at c48000c0, irq 36

          NetWinder Floating Point Emulator V0.97 (double precision)

          Console: switching to colour frame buffer device 80x25

          fb0: Virtual frame buffer device, using 1024K of video memory

          S3C2410 RTC, (c) 2004 Simtec Electronics

          s3c2410_serial0 at MMIO 0x50000000 (irq = 70) is a S3C2410

          s3c2410_serial1 at MMIO 0x50004000 (irq = 73) is a S3C2410

          s3c2410_serial2 at MMIO 0x50008000 (irq = 76) is a S3C2410

          io scheduler noop registered

          io scheduler anticipatory registered

          io scheduler deadline registered

          io scheduler cfq registered

          RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize

          S3C24XX NAND Driver, (c) 2004 Simtec Electronics

          s3c2410-nand: mapped registers at c4980000

          s3c2410-nand: timing: Tacls 10ns, Twrph0 20ns, Twrph1 10ns

          s3c2410-nand: NF_CONF is 0x8010

          NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit)

          NAND_ECC_NONE selected by board driver. This is not recommended !!

          Scanning device for bad blocks

          Creating 5 MTD partitions on "NAND 64MiB 3,3V 8-bit":

          0x00000000-0x00020000 : "bootloader"

          0x00020000-0x00030000 : "param"

          0x00030000-0x001f0000 : "kernel"

          0x00200000-0x02200000 : "rootfs"

          0x02200000-0x04000000 : "user"

          usbmon: debugfs is not available

          mice: PS/2 mouse device common for all mice

          NET: Registered protocol family 2

          IP route cache hash table entries: 1024 (order: 0, 4096 bytes)

          TCP established hash table entries: 4096 (order: 2, 16384 bytes)

          TCP bind hash table entries: 4096 (order: 2, 16384 bytes)

          TCP: Hash tables configured (established 4096 bind 4096)

          TCP reno registered

          TCP bic registered

          NET: Registered protocol family 1

          Reading data from NAND FLASH without ECC is not recommended

          VFS: Mounted root (cramfs filesystem) readonly.

          Freeing init memory: 92K

          Warning: unable to open an initial console.

          Reading data from NAND FLASH without ECC is not recommended

          sd_mod: version magic 2.6.8.1-ptx1 ARMv4 gcc-3.3 should be 2.6.14 ARMv4 gcc-3.4

          usb_storage: version magic 2.6.8.1-ptx1 ARMv4 gcc-3.3 should be 2.6.14 ARMv4 gcc-3.4

          usbvideo: version magic 2.6.8.1-ptx1 ARMv4 gcc-3.3 should be 2.6.14 ARMv4 gcc-3.4

          ov511: version magic 2.6.8.1-ptx1 ARMv4 gcc-3.3 should be 2.6.14 ARMv4 gcc-3.4



          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();