本文章主要針對FS100,S5PC100的Android4.0.4 Yaffs2文件系統移植過程,對于類似Android系統或類似Linux內核(版本高于2.6.35)有參考意義。
本文分兩部分:
1.Nandflash驅動移植
2.Yaffs2文件系統移植
一、Nandflash驅動移植
由于內核里面沒有S5PC100的Nandflash驅動,所以,我們將Nandflash的驅動文件拷貝到內核目錄中:
將s3c_nand.c拷貝到:drivers/mtd/nand/中(s3c_nand.c放到了空間共享里了://download.csdn.net/detail/mr_raptor/4848511)。
Nand驅動修改位置:
1.添加Nand物理地址
@arch/arm/mach-s5pc100/include/mach/map.h
添加如下內容:
1. // MichaelTang add for Nandflash start
2. /* NAND flash controller */
3. #define S5PC1XX_PA_NAND (0xE7200000)
4. #define S5PC1XX_SZ_NAND SZ_1M
5. // MichaelTang add for Nandflash end ----
2. 添加一個新的頭文件:
@arch/arm/mach-s5pc100/include/mach/nand.h
1. #ifndef __MACH_NAND_H
2. #define __MACH_NAND_H
3. #include < linux/mtd/partitions.h>
4. struct s3c_nand_mtd_info {
5. uint chip_nr;
6. uint mtd_part_nr;
7. struct mtd_partition *partition;
8. };
9. #endif
3. 修改寄存器頭文件
@arch/arm/plat-samsung/include/plat/regs-nand.h
在regs-nand.h中添加如下宏:
1. // MichaelTang add for nand reg start
2. /* for s3c_nand.c */
3. #define S3C_NFCONF S3C2410_NFREG(0x00)
4. #define S3C_NFCONT S3C2410_NFREG(0x04)
5. #define S3C_NFCMMD S3C2410_NFREG(0x08)
6. #define S3C_NFADDR S3C2410_NFREG(0x0c)
7. #define S3C_NFDATA8 S3C2410_NFREG(0x10)
8. #define S3C_NFDATA S3C2410_NFREG(0x10)
9. #define S3C_NFMECCDATA0 S3C2410_NFREG(0x14)
10. #define S3C_NFMECCDATA1 S3C2410_NFREG(0x18)
11. #define S3C_NFSECCDATA S3C2410_NFREG(0x1c)
12. #define S3C_NFSBLK S3C2410_NFREG(0x20)
13. #define S3C_NFEBLK S3C2410_NFREG(0x24)
14. #define S3C_NFSTAT S3C2410_NFREG(0x28)
15. #define S3C_NFMECCERR0 S3C2410_NFREG(0x2c)
16. #define S3C_NFMECCERR1 S3C2410_NFREG(0x30)
17. #define S3C_NFMECC0 S3C2410_NFREG(0x34)
18. #define S3C_NFMECC1 S3C2410_NFREG(0x38)
19. #define S3C_NFSECC S3C2410_NFREG(0x3c)
20. #define S3C_NFMLCBITPT S3C2410_NFREG(0x40)
21. #define S3C_NF8ECCERR0 S3C2410_NFREG(0x44)
22. #define S3C_NF8ECCERR1 S3C2410_NFREG(0x48)
23. #define S3C_NF8ECCERR2 S3C2410_NFREG(0x4C)
24. #define S3C_NFM8ECC0 S3C2410_NFREG(0x50)
25. #define S3C_NFM8ECC1 S3C2410_NFREG(0x54)
26. #define S3C_NFM8ECC2 S3C2410_NFREG(0x58)
27. #define S3C_NFM8ECC3 S3C2410_NFREG(0x5C)
28. #define S3C_NFMLC8BITPT0 S3C2410_NFREG(0x60)
29. #define S3C_NFMLC8BITPT1 S3C2410_NFREG(0x64)
30.
31. #define S3C_NFCONF_NANDBOOT (1<<31)
32. #define S3C_NFCONF_ECCCLKCON (1<<30)
33. #define S3C_NFCONF_ECC_MLC (1<<24)
34. #define S3C_NFCONF_ECC_1BIT (0<<23)
35. #define S3C_NFCONF_ECC_4BIT (2<<23)
36. #define S3C_NFCONF_ECC_8BIT (1<<23)
37. #define S3C_NFCONF_TACLS(x) ((x)<<12)
38. #define S3C_NFCONF_TWRPH0(x) ((x)<<8)
39. #define S3C_NFCONF_TWRPH1(x) ((x)<<4)
40. #define S3C_NFCONF_ADVFLASH (1<<3)
41. #define S3C_NFCONF_PAGESIZE (1<<2)
42. #define S3C_NFCONF_ADDRCYCLE (1<<1)
43. #define S3C_NFCONF_BUSWIDTH (1<<0)
44. 45. #define S3C_NFCONT_ECC_ENC (1<<18)
46. #define S3C_NFCONT_LOCKTGHT (1<<17)
47. #define S3C_NFCONT_LOCKSOFT (1<<16)
48. #define S3C_NFCONT_MECCLOCK (1<<7)
49. #define S3C_NFCONT_SECCLOCK (1<<6)
50. #define S3C_NFCONT_INITMECC (1<<5)
51. #define S3C_NFCONT_INITSECC (1<<4)
52. #define S3C_NFCONT_nFCE1 (1<<2)
53. #define S3C_NFCONT_nFCE0 (1<<1)
54. #define S3C_NFCONT_INITECC (S3C_NFCONT_INITSECC | S3C_NFCONT_INITMECC)
55. 56. #define S3C_NFSTAT_ECCENCDONE (1<<7)
57. #define S3C_NFSTAT_ECCDECDONE (1<<6)
58. #define S3C_NFSTAT_ILEGL_ACC (1<<5)
59. #define S3C_NFSTAT_RnB_CHANGE (1<<4)
60. #define S3C_NFSTAT_nFCE1 (1<<3)
61. #define S3C_NFSTAT_nFCE0 (1<<2)
62. #define S3C_NFSTAT_Res1 (1<<1)
63. #define S3C_NFSTAT_READY (1<<0)
64. #define S3C_NFSTAT_CLEAR ((1<<7) |(1<<6) |(1<<5) |(1<<4))
65.
66. #define S3C_NFECCERR0_ECCBUSY (1<<31)
67. // MichaelTang add for nand reg end
4. 修改平臺機器代碼初始化代碼
@arch/arm/mach-s5pc100/mach-smdkc100.c
添加如下內容:
1. // MichaelTang add for Nand
2. #include < linux/mtd/partitions.h>
3. #include < mach/nand.h>
4. ...
5. /* NAND Controller */
6. static struct resource s5pc_nand_resource[] = {
7. [0] = {
8. .start = S5PC1XX_PA_NAND,
9. .end = S5PC1XX_PA_NAND + S5PC1XX_SZ_NAND - 1,
10. .flags = IORESOURCE_MEM,
11. }
12. };
13.
14. struct platform_device s5pc_device_nand = {
15. .name = "s5pc100-nand",
16. .id = -1,
17. .num_resources = ARRAY_SIZE(s5pc_nand_resource),
18. .resource = s5pc_nand_resource,
19. };
20. struct mtd_partition s3c_partition_info[] = {
21. {
22. .name = "bootloader",
23. .offset = 0, /* for bootloader */
24. .size = SZ_1M,
25. //.mask_flags = MTD_CAP_NANDFLASH,
26. },
27. {
28. .name = "kernel",
29. .offset = MTDPART_OFS_APPEND,
30. .size = (4*SZ_1M),
31. //.mask_flags = MTD_CAP_NANDFLASH,
32. },
33. {
34. .name = "rootfs",
35. .offset = MTDPART_OFS_APPEND,
36. .size = MTDPART_SIZ_FULL,
37. },
38. };
39.
40. struct s3c_nand_mtd_info s3c_nand_mtd_part_info = {
41. .chip_nr = 1,
42. .mtd_part_nr = ARRAY_SIZE(s3c_partition_info),
43. .partition = s3c_partition_info,
44. };
45.
46. static struct platform_device *smdkc100_devices[] __initdata = {
47. ....
48. // Michaeltang add
49. &s5pc_device_nand,
50. ....
51.
52. static void __init smdkc100_machine_init(void)
53. {
54. ....
55. //MichaelTang add for Nand
56. s5pc_device_nand.dev.platform_data = &s3c_nand_mtd_part_info;
57. ....
5. 由于新添加了驅動文件,要在menuconfig中添加編譯項,并且讓修改Makefile來編譯驅動文件。
@drivers/mtd/nand/Kconfig
添加Kconfig的編譯項
1. config MTD_NAND_S3C
2. tristate "NAND Flash support for S3C SoC"
3. depends on ARCH_S5PC100 && MTD_NAND
4. help
5. This enables the NAND flash controller on the S3C.
6.
7.
8. No board specfic support is done by this driver, each board
9. must advertise a platform_device for the driver to attach.
10.
11.
12. config MTD_NAND_S3C_HWECC
13. bool "S3C NAND Hardware ECC"
14. depends on MTD_NAND_S3C
15. help
16. Enable the use of the S3C's internal ECC generator when
17. using NAND. Early versions of the chip have had problems with
18. incorrect ECC generation, and if using these, the default of
19. software ECC is preferable.
20.
21. If you lay down a device with the hardware ECC, then you will
22. currently not be able to switch to software, as there is no
23. implementation for ECC method used by the S3C
6. 添加驅動編譯依賴文件
@drivers/mtd/nand/Makefile
1. # MichaelTang add for nand start
2. obj-$(CONFIG_MTD_NAND_S3C) += s3c_nand.o
3. # MichaelTang add for nand end
7. 執行make menuconfig,將新添加的Nandflash驅動及mtd支持編譯到內核中。
選擇Kernel編譯項:
1. Device Drivers --->
2. <*> Memory Technology Device (MTD) support
3. <*> Caching block device access to MTD devices
4. 注:用于支持MTD塊設備
5. <*> NAND Device Support --->
6. <*> NAND Flash support for S3C SoC
7. [*] S3C NAND Hardware ECC
8. 注:選擇新添加的Nand設備驅動,選擇ECC硬件校驗
二、Yaffs2文件系統移植
我們的Android文件系統使用YAFFS2文件系統格式,選擇對應的支持項:
[plain] view plaincopy
1. File systems --->
2. [*] Miscellaneous filesystems --->
3. <*> YAFFS2 file system support
注:默認Linux內核里不支持YAFFS2文件系統,我們可以從yaffs的官方網站上去下載其源碼,然后給你的內核打上補丁即可://www.yaffs.net/download-yaffs-using-git
保存退出,執行make zImage。
常見問題:
問題1:
[plain] view plaincopy
1. fs/yaffs2/yaffs_vfs.c: In function 'yaffs_fill_inode_from_obj':
2. fs/yaffs2/yaffs_vfs.c:1333: error: assignment of read-only member 'i_nlink'
3. fs/yaffs2/yaffs_vfs.c: In function 'yaffs_unlink':
4. fs/yaffs2/yaffs_vfs.c:1747: error: decrement of read-only member 'i_nlink'
5. fs/yaffs2/yaffs_vfs.c: In function 'yaffs_link':
6. fs/yaffs2/yaffs_vfs.c:1782: error: assignment of read-only member 'i_nlink'
7. fs/yaffs2/yaffs_vfs.c: In function 'yaffs_rename':
8. fs/yaffs2/yaffs_vfs.c:1901: error: decrement of read-only member 'i_nlink'
提示錯誤,說給只讀的成員i_nlink賦值,出錯代碼如下:
[cpp] view plaincopy
1. inode->i_nlink = yaffs_get_obj_link_count(obj);
查看inode定義在 include/linux/fs.h
[cpp] view plaincopy
1. ......
2. /*
3. * Filesystems may only read i_nlink directly. They shall use the
4. * following functions for modification:
5. *
6. * (set|clear|inc|drop)_nlink
7. * inode_(inc|dec)_link_count
8. */
9. union {
10. const unsigned int i_nlink;
11. unsigned int __i_nlink;
12. };
13. ......
通過上面的注釋可知,我們可以直接讀取i_nlink成員,但是不能對其進行修改操作,必須使用(set|clear|inc|drop)_nlink進行修改操作。
于是,將出錯的代碼處改為:
[cpp] view plaincopy
1. // MichaelTang modify
2. set_nlink(inode, yaffs_get_obj_link_count(obj));
3. //inode->i_nlink = yaffs_get_obj_link_count(obj);
問題2:
[cpp] view plaincopy
1. fs/yaffs2/yaffs_vfs.c:440: warning: initialization from incompatible pointer type
2. fs/yaffs2/yaffs_vfs.c:445: warning: initialization from incompatible pointer type
3. fs/yaffs2/yaffs_vfs.c:447: warning: initialization from incompatible pointer type
4. fs/yaffs2/yaffs_vfs.c: In function 'yaffs_mtd_put_super':
5. fs/yaffs2/yaffs_vfs.c:2514: error: 'struct mtd_info' has no member named 'sync'
6. fs/yaffs2/yaffs_vfs.c:2515: error: 'struct mtd_info' has no member named 'sync'
7. fs/yaffs2/yaffs_vfs.c: In function 'yaffs_internal_read_super':
8. fs/yaffs2/yaffs_vfs.c:2702: error: 'struct mtd_info' has no member named 'erase'
9. fs/yaffs2/yaffs_vfs.c:2703: error: 'struct mtd_info' has no member named 'read'
10. fs/yaffs2/yaffs_vfs.c:2704: error: 'struct mtd_info' has no member named 'write'
11. fs/yaffs2/yaffs_vfs.c:2705: error: 'struct mtd_info' has no member named 'read_oob'
12. fs/yaffs2/yaffs_vfs.c:2706: error: 'struct mtd_info' has no member named 'write_oob'
13. fs/yaffs2/yaffs_vfs.c:2707: error: 'struct mtd_info' has no member named 'block_isbad'
14. fs/yaffs2/yaffs_vfs.c:2708: error: 'struct mtd_info' has no member named 'block_markbad'
15. fs/yaffs2/yaffs_vfs.c:2732: error: 'struct mtd_info' has no member named 'erase'
16. fs/yaffs2/yaffs_vfs.c:2733: error: 'struct mtd_info' has no member named 'block_isbad'
17. fs/yaffs2/yaffs_vfs.c:2734: error: 'struct mtd_info' has no member named 'block_markbad'
18. fs/yaffs2/yaffs_vfs.c:2734: error: 'struct mtd_info' has no member named 'read'
19. fs/yaffs2/yaffs_vfs.c:2734: error: 'struct mtd_info' has no member named 'write'
20. fs/yaffs2/yaffs_vfs.c:2736: error: 'struct mtd_info' has no member named 'read_oob'
21. fs/yaffs2/yaffs_vfs.c:2736: error: 'struct mtd_info' has no member named 'write_oob'
22. fs/yaffs2/yaffs_vfs.c:2757: error: 'struct mtd_info' has no member named 'erase'
23. fs/yaffs2/yaffs_vfs.c:2757: error: 'struct mtd_info' has no member named 'read'
24. fs/yaffs2/yaffs_vfs.c:2757: error: 'struct mtd_info' has no member named 'write'
25. fs/yaffs2/yaffs_vfs.c:2759: error: 'struct mtd_info' has no member named 'read_oob'
26. fs/yaffs2/yaffs_vfs.c:2759: error: 'struct mtd_info' has no member named 'write_oob'
27. make[2]: *** [fs/yaffs2/yaffs_vfs.o] 錯誤 1
28. make[1]: *** [fs/yaffs2] 錯誤 2
29. make: *** [fs] 錯誤 2
根據錯誤信息,mtd_info結構體成員沒有對應的:sync、erase、read、write等成員,找到struct mtd_info的定義:
@include/linux/mtd/mtd.h
1. struct mtd_info {
2. ......
3.
4.
5. /*
6. * Do not call via these pointers, use corresponding mtd_*()
7. * wrappers instead.
8. */
9. // 不要直接通過函數指針的文件調用這些函數,盡量使用對應的mtd_xxx()封裝函數替代,
10. // 如,要調用_sync,則使用其對應的封裝函數:mtd_sync().
11. int (*_erase) (struct mtd_info *mtd, struct erase_info *instr);
12. int (*_point) (struct mtd_info *mtd, loff_t from, size_t len,
13. size_t *retlen, void **virt, resource_size_t *phys);
14. int (*_unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
15. unsigned long (*_get_unmapped_area) (struct mtd_info *mtd,
16. unsigned long len,
17. unsigned long offset,
18. unsigned long flags);
19. int (*_read) (struct mtd_info *mtd, loff_t from, size_t len,
20. size_t *retlen, u_char *buf);
21. int (*_write) (struct mtd_info *mtd, loff_t to, size_t len,
22. size_t *retlen, const u_char *buf);
23. int (*_panic_write) (struct mtd_info *mtd, loff_t to, size_t len,
24. size_t *retlen, const u_char *buf);
25. int (*_read_oob) (struct mtd_info *mtd, loff_t from,
26. struct mtd_oob_ops *ops);
27. int (*_write_oob) (struct mtd_info *mtd, loff_t to,
28. struct mtd_oob_ops *ops);
29. int (*_get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
30. size_t len);
31. int (*_read_fact_prot_reg) (struct mtd_info *mtd, loff_t from,
32. size_t len, size_t *retlen, u_char *buf);
33. int (*_get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf,
34. size_t len);
35. int (*_read_user_prot_reg) (struct mtd_info *mtd, loff_t from,
36. size_t len, size_t *retlen, u_char *buf);
37. int (*_write_user_prot_reg) (struct mtd_info *mtd, loff_t to,
38. size_t len, size_t *retlen, u_char *buf);
39. int (*_lock_user_prot_reg) (struct mtd_info *mtd, loff_t from,
40. size_t len);
41. int (*_writev) (struct mtd_info *mtd, const struct kvec *vecs,
42. unsigned long count, loff_t to, size_t *retlen);
43. void (*_sync) (struct mtd_info *mtd);
44. int (*_lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
45. int (*_unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
46. int (*_is_locked) (struct mtd_info *mtd, loff_t ofs, uint64_t len);
47. int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs);
48. int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);
49. int (*_suspend) (struct mtd_info *mtd);
50. void (*_resume) (struct mtd_info *mtd);
51. ......
52.
53. static inline void mtd_sync(struct mtd_info *mtd)
54. {
55. if (mtd->_sync)
56. mtd->_sync(mtd);
57. }
58.
59. ......
由代碼及注釋可知,mtd_info中成員發生改變是為了讓大家使用新的mtd_xxx()封裝函數而不使用函數指針。我們有兩種方式修改代碼:
1>.直接將mtd->sync()的調用,改成mtd->_sync(),這種方式修改簡單,也沒有問題,但是和新mtd_info的初衷相悖。
2>.將mtd->sync()改成mtd_sync()
修改位置:
@fs/yaffs2/yaffs_vfs.c
@fs/yaffs2/yaffs_mtdif.c
@fs/yaffs2/yaffs_mtdif1.c
@fs/yaffs2/yaffs_mtdif2.c
問題3:
[cpp] view plaincopy
1. fs/yaffs2/yaffs_vfs.c:2967: error: implicit declaration of function 'd_alloc_root'
2. fs/yaffs2/yaffs_vfs.c:2967: warning: assignment makes pointer from integer without a cast
3.
4. make[2]: *** [fs/yaffs2/yaffs_vfs.o] 錯誤 1
5. make[1]: *** [fs/yaffs2] 錯誤 1
6. make: *** [fs] 錯誤 1
根據錯誤信息知,找不到d_alloc_root方法,原因是新的linux內核fs/dcache.c里使用d_make_root函數,所以直接將函數名換下即可。
@fs/yaffs2/yaffs_vfs.c
[cpp] view plaincopy
1. // MichaelTang modify
2. root = d_make_root(inode);
3. //root = d_alloc_root(inode);
4. yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: d_make_root done");
5. //yaffs_trace(YAFFS_TRACE_OS, "yaffs_read_super: d_alloc_root done");
問題4:
[cpp] view plaincopy
1. fs/yaffs2/yaffs_vfs.c:2392: error: implicit declaration of function 'get_sb_bdev'
2. fs/yaffs2/yaffs_vfs.c: At top level:
3. fs/yaffs2/yaffs_vfs.c:2399: error: unknown field 'get_sb' specified in initializer
4. fs/yaffs2/yaffs_vfs.c:2399: warning: initialization makes integer from pointer without a cast
5. fs/yaffs2/yaffs_vfs.c:2423: error: unknown field 'get_sb' specified in initializer
錯誤信息提示,找不到get_sb_bdev和get_sb。
分析2.6.35前的代碼可知,這兩個函數是舊內核提供的函數,新內核使用了mount_bdev和mount函數,所以我們做如下代碼修改:
第一處,針對yaffs的修改:
[cpp] view plaincopy
1. // MichaelTang modify start
2. #if 0
3. static int yaffs_read_super(struct file_system_type *fs,
4. int flags, const char *dev_name,
5. void *data, struct vfsmount *mnt)
6. {
7.
8.
9. return get_sb_bdev(fs, flags, dev_name, data,
10. yaffs_internal_read_super_mtd, mnt);
11. }
12.
13.
14. static struct file_system_type yaffs_fs_type = {
15. .owner = THIS_MODULE,
16. .name = "yaffs",
17. .get_sb = yaffs_read_super,
18. .kill_sb = kill_block_super,
19. .fs_flags = FS_REQUIRES_DEV,
20. };
21. #else
22. static struct super_block *yaffs_read_super(struct file_system_type *fs,
23. int flags, const char *dev_name,
24. void *data)
25. {
26. return mount_bdev(fs, flags, dev_name, data,
27. yaffs_internal_read_super_mtd);
28. }
29. static struct file_system_type yaffs_fs_type = {
30. .owner = THIS_MODULE,
31. .name = "yaffs",
32. //.get_sb = yaffs_read_super,
33. .mount = yaffs_read_super,
34. .kill_sb = kill_block_super,
35. .fs_flags = FS_REQUIRES_DEV,
36. };
37. #endif
38. // MichaelTang modify end
第二處,針對Yaffs2的修改:
[cpp] view plaincopy
1. #ifdef CONFIG_YAFFS_YAFFS2
2.
3. static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data, int silent)
5. {
6. return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;
7. }
8.
9.
10. // MichaelTang modify start
11. #if 0
12. static int yaffs2_read_super(struct file_system_type *fs,
13. int flags, const char *dev_name, void *data,
14. struct vfsmount *mnt)
15. {
16. return get_sb_bdev(fs, flags, dev_name, data, yaffs2_internal_read_super_mtd, mnt);
18. }
19. static struct file_system_type yaffs2_fs_type = {
20. .owner = THIS_MODULE,
21. .name = "yaffs2",
22. .get_sb = yaffs2_read_super,
23. .kill_sb = kill_block_super,
24. .fs_flags = FS_REQUIRES_DEV,
25. };
26. #else
27. static struct super_block *yaffs2_read_super(struct file_system_type *fs,
28. int flags, const char *dev_name,
29. void *data)
30. {
31. return mount_bdev(fs, flags, dev_name, data, yaffs2_internal_read_super_mtd);
33. }
34. static struct file_system_type yaffs2_fs_type = {
35. .owner = THIS_MODULE,
36. .name = "yaffs2",
37. //.get_sb = yaffs2_read_super,
38. .mount = yaffs2_read_super,
39. .kill_sb = kill_block_super,
40. .fs_flags = FS_REQUIRES_DEV,
41. };
42. #endif
43. // MichaelTang modify end
問題5:
error: 'MTD_OOB_AUTO' undeclared
找不到符號MTD_OOB_AUTO,新內核里名字發生了改變:
@include/mtd/mtd-abi.h
MTD_OOB_AUTO -> MTD_OPS_AUTO_OOB
所以源碼中所有的位置都改一下即可,共有2個文件使用到:
@fs/yaffs2/yaffs_mtdif1.c
@fs/yaffs2/yaffs_mtdif2.c
可能出的問題:
end_writeback找不到符號
解決方法:end_writeback(inode)改成clear_inode(inode)
另:隨著Android4.0.4版本的更新,其文件系統體積也直線提升,生成的映像有250M左右,由于S5PC100內存只有256M,所以使用UBOOT燒寫時就可能出問題,通過USB或tftp下載的文件系統將Uboot代碼覆蓋了,我們將uboot的運行地址放到高的幾M處。
假如,默認運行地址為0x27e00000,新運行地址為0x2f000000,S5PC100物理內存空間(0x20000000~0x30000000共256M)。
grep "0x27e00000" -R ./ 替換了所有的地址就行了
主要是config.h、smdkc100.h和匯編代碼文件中定義的幾個和地址搬運有關的宏。