Uboot 挂载Yaffs2文件系统问题分析流程

1、问题描述

        我们的一款设备使用海思平台,设备外挂32MB的sp nor flash作为程序存储使用,512MB spi nand flash 格式化为yaffs2系统作为数据存储使用。当设备需要升级的时候,将升级程序放到nand下面,重新启动系统,然后uboot阶段使用yaffs命令扫描并读取nand里面的文件进行升级。问题在这里出现了,当uboot阶段挂载YAFFS2文件系统时,有些设备能正常识别NAND flash中的文件内容,有些设备只能识别lost+found目录。但内核阶段所有设备都能正常挂载和访问文件系统,如下所述。
  • 平台: 海思平台
  • NAND Flash: 512MB, 256KB块大小, 4KB页大小, 200B OOB
  • Uboot版本: 2010.06
  • 内核版本: 3.10.y
内核阶段nand里面的文件,系统启动以后,nand挂载到/mnt/nand下面
[root@tmkj:/mnt/nand]$ls -alh
total 1157
drwxr-xr-x    1 root     root        4.0K Jun 15 14:14 .
drwxrwxr-x    1 1037     13           308 Jan  1  1970 ..
drwxrwxrwx    1 root     root        4.0K Nov 25  2025 bzqmp3
-rw-r--r--    1 root     root           0 Nov 15  2025 bzqmp3_update
drwxr-xr-x    1 root     root        4.0K Jun 15 11:09 download
-rwxr-xr-x    1 root     root      365.7K Jun 12 15:25 flash_erase
-rwxr-xr-x    1 root     root      325.7K Jun 12 15:25 flashcp
drwxr-xr-x    1 root     root        4.0K Dec  9  2024 ftppic
-rw-r--r--    1 root     root           0 Feb 22  1970 gps_metadata1.txt
-rw-r--r--    1 root     root         888 Jun 15 14:14 linebzq.ini
drwxr-xr-x    1 root     root        4.0K May 15 08:57 log
drwx------    1 root     root        4.0K Jan  1  1970 lost+found
drwxr-xr-x    1 root     root        4.0K Apr 24  2023 pic
drwxr-xr-x    1 root     root        4.0K Jun 15 08:42 rslog
-rw-r--r--    1 root     root         231 May 18 10:47 shell_update.log
-rw-r--r--    1 root     root      430.0K Jun 15 14:10 uboot-3521a
uboot阶段扫描到的文件
tiamaes # ymount /flash
yaffs: Mounting /flash
tiamaes # yls /flash
lost+found

2、问题分析流程

2.1、分析NAND硬件信息

从启动日志获取硬件配置
SPI Nand(cs 1) ID: 0xb4 0x68 Name:"5F4GQ4UCYIG"
Block:256KB Page:4KB Chip:512MB*1 OOB:200B ECC:24bit/1K 
SPI Nand total size: 512MB
关键参数:
  • 块大小: 256KB
  • 页大小: 4KB
  • OOB大小: 200B
  • ECC: 24bit/1K
对比能正常启动的设备,发现2者信息完全一样,异常排除nand异常问题。

2.2、检查Tags格式

Uboot: fs/yaffs2/yaffs_mtdif2.c
ops.ooblen = sizeof(yaffs_PackedTags2);  // 28字节tags格式
修改位置: fs/yaffs2/yaffs_mtdif2.c
在nandmtd2_QueryNANDBlock函数中添加日志:
int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
			    yaffs_BlockState * state, int *sequenceNumber)
{
    // ... 原有代码 ...
    
    nandmtd2_ReadChunkWithTagsFromNAND(dev,
                       blockNo * dev->nChunksPerBlock, NULL,
                       &t);

    /* 添加调试日志 */
    printf("QUERY: Block %d: chunkUsed=%d seq=%d eccResult=%d objectId=%d chunkId=%d\n",
           blockNo, t.chunkUsed, t.sequenceNumber, t.eccResult, t.objectId, t.chunkId);
    
    if (t.chunkUsed) {
        *sequenceNumber = t.sequenceNumber;
        *state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
    } else {
        *sequenceNumber = 0;
        *state = YAFFS_BLOCK_STATE_EMPTY;
    }
    // ...
}
编译并运行后查看日志
QUERY: Block 0: chunkUsed=1 seq=-1761585747 eccResult=1 objectId=336 chunkId=3
QUERY: Block 1: chunkUsed=1 seq=-1761580551 eccResult=1 objectId=1323 chunkId=5
QUERY: Block 2: chunkUsed=1 seq=-1761585746 eccResult=1 objectId=1045 chunkId=0
...
关键发现:
  1. chunkUsed=1 - 块确实有数据
  2. seq=负数 - 序列号显示为负值!
  3. eccResult=1 - ECC已修复但数据有效
  4. 各种objectId - 存在多个对象

2.3、分析序列号符号问题

目的: 确认序列号是负数的原因
添加更详细的日志: fs/yaffs2/yaffs_mtdif2.c
/* Debug: Log raw bytes for first few blocks */
if(blockNo < 5) {
    yaffs_PackedTags2 *pt = (yaffs_PackedTags2 *)dev->spareBuffer;
    __u8 *bytes = (__u8*)pt;
    printf("RAW: Block %d tags bytes: %02x %02x %02x %02x | %02x %02x %02x %02x | %02x %02x %02x %02x | %02x %02x %02x %02x\n",
           blockNo, bytes[0], bytes[1], bytes[2], bytes[3],
           bytes[4], bytes[5], bytes[6], bytes[7],
           bytes[8], bytes[9], bytes[10], bytes[11],
           bytes[12], bytes[13], bytes[14], bytes[15]);
    printf("RAW: Block %d seq as unsigned: %u (0x%08x)\n", blockNo, t.sequenceNumber, t.sequenceNumber);
}
printf("QUERY: Block %d: chunkUsed=%d seq=%d eccResult=%d objectId=%d chunkId=%d\n",
       blockNo, t.chunkUsed, t.sequenceNumber, t.eccResult, t.objectId, t.chunkId);
编译运行后的日志
RAW: Block 0 tags bytes: ad 55 00 97 | 50 01 00 00 | 03 00 00 00 | 00 10 00 00
RAW: Block 0 seq as unsigned: 2533381549 (0x970055ad)
QUERY: Block 0: chunkUsed=1 seq=-1761585747 eccResult=1 objectId=336 chunkId=3

RAW: Block 1 tags bytes: f9 69 00 97 | 2b 05 00 00 | 05 00 00 00 | 00 10 00 00
RAW: Block 1 seq as unsigned: 2533386745 (0x970069f9)
QUERY: Block 1: chunkUsed=1 seq=-1761580551 eccResult=1 objectId=1323 chunkId=5

关键发现:
  1. RAW字节: ad 55 00 97 (小端序) = 0x970055ad
  2. 无符号值: 2533381549 - 正常的大整数
  3. 有符号值: -1761585747 - 负数!
  4. NAND中数据存储正确,但打印时被解释为有符号数

2.4、检查扫描过程

目的: 确认块是否被加入扫描列表
修改位置: fs/yaffs2/yaffs_guts.c - yaffs_ScanBackwards函数
在关键位置添加日志:
static int yaffs_ScanBackwards(yaffs_Device * dev)
{
    // ... 变量声明 ...
    
    printf("SCAN: Starting scan, %d blocks to scan (from iterator %d to %d)\n",
           nBlocksToScan, startIterator, endIterator);
    
    /* Scan all the blocks to determine their state */
    for (blk = dev->internalStartBlock; blk <= dev->internalEndBlock; blk++) {
        bi = yaffs_GetBlockInfo(dev, blk);
        yaffs_ClearChunkBits(dev, blk);
        bi->pagesInUse = 0;
        bi->softDeletions = 0;

        yaffs_QueryInitialBlockState(dev, blk, &state, &sequenceNumber);

        bi->blockState = state;
        bi->sequenceNumber = sequenceNumber;
        
        printf("SCAN: Checking block %d: state=%d seq=%d\n", blk, state, sequenceNumber);

        if(state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
            printf("SCAN: Block %d needs scanning check\n", blk);
            
            /* Determine the highest sequence number */
            if (dev->isYaffs2 &&
                sequenceNumber >= YAFFS_LOWEST_SEQUENCE_NUMBER &&
                sequenceNumber < YAFFS_HIGHEST_SEQUENCE_NUMBER) {

                blockIndex[nBlocksToScan].seq = sequenceNumber;
                blockIndex[nBlocksToScan].block = blk;

                nBlocksToScan++;

                if (sequenceNumber >= dev->sequenceNumber) {
                    dev->sequenceNumber = sequenceNumber;
                    printf("SCAN: Block %d added to scan list, seq=%d, total=%d\n", 
                           blk, sequenceNumber, nBlocksToScan);
                }
            } else if (dev->isYaffs2) {
                printf("SCAN: Block %d FAILED sequence check: seq=%d (LOWEST=%d HIGHEST=%d)\n",
                       blk, sequenceNumber, YAFFS_LOWEST_SEQUENCE_NUMBER, YAFFS_HIGHEST_SEQUENCE_NUMBER);
            }
        }
    }
    
    printf("SCAN: Scan completed, %d blocks to scan, alloc_failed=%d\n", 
           nBlocksToScan, alloc_failed);
    
    // ... 继续处理扫描结果 ...
}

编译运行后的日志:
SCAN: Starting scan, 0 blocks to scan (from iterator -1 to 0)
SCAN: Block loop completed, alloc_failed=0
SCAN: Scan completed, alloc_failed=0
关键发现:
  1. 0 blocks to scan - 没有块被加入扫描列表!
  2. 尽管QUERY显示所有块都有数据,但扫描时没有被加入
  3. 说明问题在序列号范围检查

2.5、序列号没有扫描的原因

目的: 找出序列号检查失败的具体原因
分析检查条件:
if (dev->isYaffs2 &&
    sequenceNumber >= YAFFS_LOWEST_SEQUENCE_NUMBER &&
    sequenceNumber < YAFFS_HIGHEST_SEQUENCE_NUMBER)
检查常量定义 (fs/yaffs2/yaffs_guts.h):
#define YAFFS_LOWEST_SEQUENCE_NUMBER  0x00001000  // 4096
#define YAFFS_HIGHEST_SEQUENCE_NUMBER 0xEFFFFF00
实际计算:
sequenceNumber = -1761585747 (有符号)
YAFFS_LOWEST_SEQUENCE_NUMBER = 4096

检查: -1761585747 >= 4096
结果: FALSE ❌
根本原因确认:
  • NAND中实际值: 0x970055ad = 2533381549 (无符号)
  • 变量声明类型: int (有符号)
  • 解释为有符号: -1761585747
  • 检查失败: 负数 < 4096
检查变量声明
位置: fs/yaffs2/yaffs_guts.c
static int yaffs_ScanBackwards(yaffs_Device * dev)
{
    // ...
    int sequenceNumber;  // ❌ 错误:声明为有符号int
    // ...
}
对比内核实现
内核: linux-3.10.y/fs/yaffs2/yaffs_yaffs2.c
static int yaffs2_scan_backwards(struct yaffs_dev *dev)
{
    // ...
    u32 seq_number;  // ✅ 正确:声明为无符号u32
    // ...
}
问题确认: uboot使用int而内核使用u32,这是数据类型不匹配的bug!

2.6、修改问题

修改1: yaffs_ScanBackwards函数
文件: fs/yaffs2/yaffs_guts.c
// 修改前
yaffs_Object *hardList = NULL;
yaffs_BlockInfo *bi;
int sequenceNumber;  // ❌ 有符号
yaffs_ObjectHeader *oh;

// 修改后
yaffs_Object *hardList = NULL;
yaffs_BlockInfo *bi;
unsigned sequenceNumber;  // ✅ 无符号
yaffs_ObjectHeader *oh;
修改2: yaffs_Scan函数 (相同问题)
文件: fs/yaffs2/yaffs_guts.c
// 修改前
yaffs_Object *hardList = NULL;
yaffs_BlockInfo *bi;
int sequenceNumber;  // ❌ 有符号
yaffs_ObjectHeader *oh;

// 修改后
yaffs_Object *hardList = NULL;
yaffs_BlockInfo *bi;
unsigned sequenceNumber;  // ✅ 无符号
yaffs_ObjectHeader *oh;

2.7、验证问题

编译完成以后正常识别。
tiamaes # yls /flash
log
bzqmp3_update
gps_metadata1.txt
ftppic
shell_update.log
bzqmp3
pic
flash_erase
flashcp
rslog
download
uboot-3521a
linebzq.ini
lost+found

3、问题分析2

        问题解决以后,又有另外1个疑问,问什么有的设备正常,有的设备异常,问什么Uboot异常,而内核整正常,带着疑问,我们继续分析

3.1、Uboot识别NAND异常问题分析

3.1.1、根本原因

        Uboot中sequenceNumber变量声明为有符号整数(int),而内核中声明为无符号整数(u32)。当NAND flash中的序列号增长到一定值后,作为有符号数解释会变成负数,导致序列号范围检查失败。

3.1.2、数据类型分析

序列号的临界点
32位整数范围: 0x00000000 ~ 0xFFFFFFFF

当作为有符号int解释:
├────────────────────────────────────┤
│                                    │
0x00000000                    0x7FFFFFFF          0xFFFFFFFF
    │                              │                    │
    正数范围 (0 ~ 2147483647)        负数范围 (-1 ~ -2147483648)
    │                              │                    │
    └─────── ✅能识别 ──────────┘    └────── ❌不能识别 ─────┘
    
当作为无符号u32解释:
├────────────────────────────────────────────────────┤
│                                                     │
0x00000000                                      0xFFFFFFFF
    │                                                   │
    └────────────── ✅ 正常工作 ───────────────────┘
YAFFS2序列号常量
#define YAFFS_LOWEST_SEQUENCE_NUMBER  0x00001000  // 4096
#define YAFFS_HIGHEST_SEQUENCE_NUMBER 0xEFFFFF00

3.2、内核代码详解

3.2.1、 数据结构定义

文件: linux-3.10.y/fs/yaffs2/yaffs_guts.h
struct yaffs_ext_tags {
    unsigned chunk_used;
    unsigned obj_id;
    unsigned chunk_id;
    unsigned n_bytes;
    enum yaffs_ecc_result ecc_result;
    unsigned block_bad;
    unsigned is_deleted;
    unsigned serial_number;
    unsigned seq_number;        // ✅ 无符号类型
    // ...
};

3.2.2、 序列号初始化

文件: linux-3.10.y/fs/yaffs2/yaffs_yaffs2.c
static int yaffs2_scan_backwards(struct yaffs_dev *dev)
{
    u32 seq_number;  // 使用u32无符号类型
    
    // 初始化序列号
    dev->seq_number = YAFFS_LOWEST_SEQUENCE_NUMBER;  // = 0x00001000 (4096)
    
    // ... 扫描代码
}

3.2.3、序列号递增逻辑

文件: linux-3.10.y/fs/yaffs2/yaffs_guts.c
static int yaffs_find_alloc_block(struct yaffs_dev *dev)
{
    // 每次分配新块时,序列号递增
    dev->seq_number++;           // 序列号自增
    bi->seq_number = dev->seq_number;  // 写入块信息
    
    yaffs_trace(YAFFS_TRACE_ALLOCATE,
        "Allocated block %d, seq %d, %d left",
        dev->alloc_block_finder, dev->seq_number,
        dev->n_erased_blocks);
    return dev->alloc_block_finder;
}

3.2.4、 序列号存储到NAND

文件: linux-3.10.y/fs/yaffs2/yaffs_yaffs2.c
// 写入chunk时,将序列号存储到tags
tags.seq_number = bi->seq_number;

3.2.5、 扫描时的序列号检查

文件: linux-3.10.y/fs/yaffs2/yaffs_yaffs2.c
// 扫描块时,检查序列号是否在有效范围内
if (seq_number >= YAFFS_LOWEST_SEQUENCE_NUMBER &&
    seq_number < YAFFS_HIGHEST_SEQUENCE_NUMBER) {
    // 加入扫描列表
    block_index[n_to_scan].seq = seq_number;
    block_index[n_to_scan].block = blk;
    n_to_scan++;
    
    // 更新最大序列号
    if (seq_number >= dev->seq_number)
        dev->seq_number = seq_number;
} else {
    // 序列号异常
    yaffs_trace(YAFFS_TRACE_SCAN,
        "Block scanning block %d has bad sequence number %d",
        blk, seq_number);
}

3.3、Uboot代码分析

修复前的Bug
文件: fs/yaffs2/yaffs_guts.c
static int yaffs_ScanBackwards(yaffs_Device * dev)
{
    yaffs_ExtendedTags tags;
    int blk;
    int blockIterator;
    // ...
    int sequenceNumber;  // ❌ 错误:声明为有符号int
    // ...
}
序列号检查逻辑
文件: fs/yaffs2/yaffs_guts.c
// 与内核相同的检查逻辑
if (dev->isYaffs2 &&
    sequenceNumber >= YAFFS_LOWEST_SEQUENCE_NUMBER &&
    sequenceNumber < YAFFS_HIGHEST_SEQUENCE_NUMBER) {
    
    blockIndex[nBlocksToScan].seq = sequenceNumber;
    blockIndex[nBlocksToScan].block = blk;
    nBlocksToScan++;
    
    if (sequenceNumber >= dev->sequenceNumber) {
        dev->sequenceNumber = sequenceNumber;
    }
}

3.4、能正常工作的情况

设备状态
  • NAND flash是新格式化的
  • 设备使用时间较短
  • 文件写入/删除操作较少
序列号范围
序列号: 0x00001000 ~ 0x7FFFFFFF
       (4096 ~ 2147483647)
       
作为有符号int: 正数
比较结果: sequenceNumber >= 4096 ✅
扫描结果: nBlocksToScan > 0
实际例子
Block 0: sequenceNumber = 0x00005000 (20480)
作为有符号: 20480 (正数)
20480 >= 4096 ✅ 通过检查

→ 块被加入扫描列表 ✅

Block 1: sequenceNumber = 0x00006000 (24576)
作为有符号: 24576 (正数)
24576 >= 4096 ✅ 通过检查

→ 块被加入扫描列表 ✅

结果: 所有块正常扫描,文件系统完全识别

3.5、不能正常工作的情况

设备状态
  • NAND flash已使用较长时间
  • 经历了大量文件操作
  • 垃圾回收频繁发生
  • 序列号已增长到高位
序列号范围
序列号: 0x80000000 ~ 0xFFFFFFFF
       (2147483648 ~ 4294967295)

作为有符号int: 负数 (-2147483648 ~ -1)
比较结果: sequenceNumber < 4096 ❌
扫描结果: nBlocksToScan = 0
实际例子(设备情况)
Block 0: sequenceNumber = 0x970055ad
RAW bytes: ad 55 00 97 (小端序存储)

作为无符号 (正确): 2533381549
作为有符号 (错误): -1761585747 ❌

检查: -1761585747 >= 4096 → FALSE ❌
结果: 块不被加入扫描列表

Block 1: sequenceNumber = 0x970069f9
作为有符号: -1761580551 ❌
检查: -1761580551 >= 4096 → FALSE ❌
结果: 块不被加入扫描列表

最终结果: nBlocksToScan = 0
只创建了root和lost+found对象,其他文件无法识别
Debug日志分析
QUERY: Block 0: chunkUsed=1 seq=-1761585747 eccResult=1 objectId=336 chunkId=3
QUERY: Block 1: chunkUsed=1 seq=-1761580551 eccResult=1 objectId=1323 chunkId=5
QUERY: Block 2: chunkUsed=1 seq=-1761585746 eccResult=1 objectId=1045 chunkId=0
...

SCAN: Starting scan, 0 blocks to scan (from iterator -1 to 0)
SCAN: Block loop completed, alloc_failed=0
SCAN: Scan completed, alloc_failed=0
可以看到:
  • 所有块都显示chunkUsed=1(有数据)
  • 序列号打印为负数
  • 0 blocks to scan - 没有块被加入扫描列表

3.6、序列号增长过程

初始状态(新格式化)
设备状态: 出厂/新格式化
序列号: 0x00001000 (4096)
已分配块数: 0
文件数量: 少量
使用一段时间后
设备状态: 正常使用
序列号: 0x00010000 (65536) ~ 0x00100000 (16777216)
已分配块数: 数百到数千
文件数量: 中等
能否识别: ✅ 能识别
大量使用后
设备状态: 长期使用
序列号: 0x01000000 (16777216) ~ 0x7FFFFFFF (2147483647)
已分配块数: 数千到数万
文件数量: 大量
能否识别: ✅ 能识别(接近临界点)
超过临界点(问题状态)
设备状态: 长期大量使用
序列号: 0x80000000 (2147483648) ~ 0xFFFFFFFF (4294967295)
已分配块数: 数万以上
文件数量: 大量
能否识别: ❌ 不能识别
原因: 序列号作为有符号数变成负数

3.7、为什么内核始终正常工作

内核使用正确的数据类型
// 内核: linux-3.10.y/fs/yaffs2/yaffs_yaffs2.c:1355
u32 seq_number;  // ✅ 无符号,永远正确

// Uboot (修复前): fs/yaffs2/yaffs_guts.c:5969  
int sequenceNumber;  // ❌ 有符号,序列号大时会出错
内核处理能力
序列号完整范围 (u32):
0x00000000 ~ 0xEFFFFF00
   ↓                  ↓
   最小序列号         最大有效序列号
   
即使超过0x80000000,作为u32仍然是正数
0x970055ad = 2533381549 ✅ 内核正确处理

3.8、实际设备分析

设备NAND flash状态
从debug日志分析:
Block 0: seq=0x970055ad (2533381549)
Block 1: seq=0x970069f9 (2533386745)
Block 2: seq=0x970055ae (2533381550)
...

序列号集中在: 0x97000000 左右
平均序列号: ~2,533,000,000
这表明:
  1. 设备已使用很长时间
  • 序列号从4096增长到25亿
  • 假设平均每次分配递增1,约25亿次块分配操作
  1. 经历过大量文件操作
  • 文件创建、删除、修改
  • 垃圾回收频繁发生
  1. 处于稳定使用状态
  • 序列号连续增长
  • NAND健康状态良好(ECC修复成功)
设备使用历史推断
新设备 (seq ≈ 4096)
    ↓
少量使用 (seq ≈ 65536)
    ↓
中等使用 (seq ≈ 16777216)
    ↓
大量使用 (seq ≈ 2147483648) ← 临界点
    ↓
现在的状态 (seq ≈ 2533381549) ← 超过临界点

4、修复方案

4.1、修复内容

文件: fs/yaffs2/yaffs_guts.c
修改位置1: (yaffs_Scan函数)
// 修改前
int sequenceNumber;

// 修改后
unsigned sequenceNumber;
修改位置2: (yaffs_ScanBackwards函数)
// 修改前
int sequenceNumber;

// 修改后  
unsigned sequenceNumber;

4.2、修复效果

修复前:
SCAN: Starting scan, 0 blocks to scan (from iterator -1 to 0)
SCAN: Scan completed, alloc_failed=0
结果: 只识别lost+found

修复后:
SCAN: Block 0 needs scanning, seq=2533381549, totalToScan=1
SCAN: Block 1 needs scanning, seq=2533386745, totalToScan=2
...
SCAN: Starting scan, 1200 blocks to scan (from iterator -1 to 1199)
SCAN: Scan completed, alloc_failed=0
结果: 完整识别所有文件和目录

5、技术总结

5.1、问题本质

YAFFS2文件系统的序列号设计:
  • 初始值: 0x00001000 (4096)
  • 最大值: 0xEFFFFF00
  • 数据类型: 应为无符号整数
当序列号超过0x80000000时:
  • 无符号解释: 正常的大整数
  • 有符号解释: 负数(-2147483648 ~ -1)

5.2、为什么早期版本没有发现

  1. 开发阶段: 设备使用时间短,序列号小
  2. 测试阶段: 测试数据量有限,序列号增长慢
  3. 初期产品: 用户使用时间不长,问题未暴露

5.3、什么时候问题会显现

设备满足以下条件时问题会出现:
  • 设备已使用数月到数年
  • NAND flash经历了大量写入/删除
  • 序列号增长超过0x80000000 (21亿)
  • 大约需要数百万到数千万次块分配操作

5.4、为什么内核不受影响

Linux内核从一开始就使用正确的u32类型:
  • 无论序列号多大都能正确处理
  • 不会出现符号解释错误
  • YAFFS2文件系统设计时就考虑了完整的序列号范围

6、经验教训

类型选择的最佳实践
对于可能增长到大数值的计数器/序列号:
// ❌ 错误做法
int counter;           // 21亿后溢出为负
long counter;          // 仍然可能有问题

// ✅ 正确做法
unsigned int counter;  // 可到42亿
u32 counter;           // 明确无符号32位
u64 counter;           // 更大范围

6.1、移植代码时的注意事项

  1. 保持数据类型一致: 与原始实现保持相同的类型定义
  2. 注意平台差异: 不同平台int/long大小可能不同
  3. 使用标准类型: u32/u64等明确宽度的类型
  4. 充分测试边界值: 测试最大值、溢出等情况

6.2、长期运行设备的设计考虑

  1. 序列号规划: 选择足够大的数据类型
  2. 监控机制: 监控序列号增长情况
  3. 兼容性设计: 考虑序列号回绕的情况
  4. 升级策略: 及时修复发现的bug

结论

        该问题是由于uboot移植YAFFS2代码时,将sequenceNumber错误地声明为有符号整数int,而应该使用无符号整数u32或unsigned int。当NAND flash中的序列号增长到0x80000000以上时,作为有符号数解释变成负数,导致序列号范围检查失败,uboot无法正确扫描文件系统。修复后,uboot使用与内核一致的无符号类型,能够正确处理完整的序列号范围,无论序列号增长到多大都能正常工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值