百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Linux系统移植之—Nand flash驱动编写与移植,学Linux的先收藏

gudong366 2025-07-06 12:56 10 浏览

Linux系统要跑起来,除了上几章节讲到的uboot、kernel、文件系统的移植,还有一个不可缺少的——Nand flash驱动的移植,搞linux的或者android底层驱动的先收藏,以后工作中会遇到的。

说明:
本人近期会陆续上传IT编程相关的资料和视频教程,可以关注一下互相交流:C C++ Java python linux ARM 嵌入式 物联网等。
想学编程的朋友进入主页即可看到相关教程和资料。

Nand flash的工作原理

1.1 Nand flash 芯片工作原理

1.1.1 芯片内部存储布局及存储操作特点

1.1.2 重要芯片引脚功能

1.1.3 寻址方式

1.1.4 Nand flash 主要内设命令详细介绍

1.2 Nand Flash 控制器工作原理

1.2.1 Nand Flash 控制器特性

1.2.2 Nand Flash 控制器工作原理

1.3 Nand flash 控制器中特殊功能寄存器详细介绍

1.4 Nand Flash 控制器中的硬件 ECC 介绍

1.4.1 ECC 产生方法

1.4.2 ECC 生成器工作过程

1.4.3 ECC 的运用

2 在 ADS 下 flash 烧写程序

2.1 ADS 下 flash 烧写程序原理及结构

2.2 第三层实现说明

2.1.1 特殊功能寄存器定义

2.1.2 操作的函数实现

2.3 第二层实现说明

2.3.1 Nand Flash 初始化

2.3.3 获取 Nand flash ID

2.3.4 Nand flash 写入

2.3.5 Nand flash 读取

2.3.6 Nand flash 标记坏块

2.3.7 Nand Flash 检查坏块

2.3.8 擦除指定块中数据

2.4 第一层的实现


1 Nand flash 工作原理

S3C2410 板的 Nand Flash 支持由两部分组成:Nand Flash 控制器(集成在 S3C2410 CPU)和 Nand Flash 存储

芯片(K9F1208U0B)两大部分组成。当要访问 Nand Flash 中的数据时,必须通过 Nand Flash 控制器发送命

令才能完成。所以, Nand Flash 相当于 S3C2410 的一个外设,而不位于它的内存地址区.

1.1 Nand flash 芯片工作原理

Nand flash 芯片型号为 Samsung K9F1208U0B,数据存储容量为 64MB,采用块页式存储管理。8 个 I/O

引脚充当数据、地址、命令的复用端口。

1.1.1 芯片内部存储布局及存储操作特点

一片 Nand flash 为一个设备(device), 其数据存储分层为:

1 设备(Device) = 4096 块(Blocks)

1 块(Block) = 32 页/行(Pages/rows) ;页与行是相同的意思,叫法不一样

1 块(Page) = 528 字节(Bytes) = 数据块大小(512Bytes) + OOB 块大小(16Bytes)

在每一页中,最后 16 个字节(又称 OOB)用于 Nand Flash 命令执行完后设置状态用,剩余 512 个字节又

分为前半部分和后半部分。可以通过 Nand Flash 命令 00h/01h/50h 分别对前半部、后半部、OOB 进行定位通过

Nand Flash 内置的指针指向各自的首地址。

存储操作特点:

1. 擦除操作的最小单位是块。

2. Nand Flash 芯片每一位(bit)只能从 1 变为 0,而不能从 0 变为 1,所以在对其进行写入操作之前要一定将相应

块擦除(擦除即是将相应块得位全部变为 1).

3. OOB 部分的第六字节(即 517 字节)标志是否是坏块,如果不是坏块该值为 FF,否则为坏块。

4. 除 OOB 第六字节外,通常至少把 OOB 的前 3 个字节存放 Nand Flash 硬件 ECC 码(关于硬件 ECC 码请参看

Nandflash 控制器一节).

1.1.2 重要芯片引脚功能

I/O0-I/O7:复用引脚。可以通过它向 nand flash 芯片输入数据、地址、nand flash 命令以及输出数据和操作

状态信息。

CLE(Command Latch Enable): 命令锁存允许

ALE(Address Lactch Enable): 地址锁存允许

-CE: 芯片选择

-RE: 读允许

-WE: 写允许

-WP: 在写或擦除期间,提供写保护

R/-B: 读/忙输出

1.1.3 寻址方式

Samsung K9F1208U0B Nand Flash 片内寻址采用 26 位地址形式。从第 0 位开始分四次通过 I/O0-I/O7 进行

传送,并进行片内寻址。具体含义如下:

0-7 位:字节在上半部、下半部及 OOB 内的偏移地址

8 位:值为 0 代表对一页内前 256 个字节进行寻址

值为 1 代表对一页内后 256 个字节进行寻址

9-13 位:对页进行寻址 14-25 位:对块进行寻址

当传送地址时,从位 0 开始

1.1.4 Nand flash 主要内设命令详细介绍

Nand Flash 命令执行是通过将命令字送到 Nand Flash 控制器的命令寄存器来执行。

Nand Flash 的命令是分周期执行的,每条命令都有一个或多个执行周期,每个执行周期都有相映代码表示该周

期将要执行的动作。

主要命令有:Read 1、Read 2、Read ID、Reset、Page Program、Block Erase、Read Status。

详细介绍如下:

1. Read 1:

功能:表示将要读取 Nand flash 存储空间中一个页的前半部分,并且将内置指针定位到前半部分的第一个字节。

命令代码:00h

2. Read 2:

功能:表示将要读取 Nand flash 存储空间中一个页的后半部分,并且将内置指针定位到后半部分的第一个字节。

命令代码:01h

3. Read ID:

功能:读取 Nand flash 芯片的 ID 号

命令代码:90h

4. Reset:

功能:重启芯片。

命令代码:FFh

5. Page Program:

功能:对页进行编程命令, 用于写操作。

命令代码:首先写入 00h(A 区)/01h(B 区)/05h(C 区), 表示写入那个区; 再写入 80h 开始编程模式(写入模式),接

下来写入地址和数据; 最后写入 10h 表示编程结束.

6. Block Erase

功能:块擦除命令。

命令代码:首先写入 60h 进入擦写模式,然后输入块地址; 接下来写入 D0h, 表示擦写结束.

7. Read Status

功能:读取内部状态寄存器值命令。

命令代码:70h

1.2 Nand Flash 控制器工作原理

对 Nand Flash 存储芯片进行操作, 必须通过 Nand Flash 控制器的专用寄存器才能完成。所以,不能对 Nand

Flash 进行总线操作。而 Nand Flash 的写操作也必须块方式进行。对 Nand Flash 的读操作可以按字节读取。

1.2.1 Nand Flash 控制器特性

1. 支持对 Nand Flash 芯片的读、检验、编程控制

2. 如果支持从 Nand Flash 启动, 在每次重启后自动将前 Nand Flash 的前 4KB 数据搬运到 ARM 的内部 RAM 中

3. 支持 ECC 校验

1.2.2 Nand Flash 控制器工作原理

Nand Flash 控制器在其专用寄存器区(SFR)地址空间中映射有属于自己的特殊功能寄存器,就是通过将 Nand

Flash 芯片的内设命令写到其特殊功能寄存器中,从而实现对 Nand flash 芯片读、检验和编程控制的。特殊功能

寄存器有:NFCONF、NFCMD、NFADDR、NFDATA、NFSTAT、NFECC。寄存详细说明见下一节。

1.3 Nand flash 控制器中特殊功能寄存器详细介绍

1. 配置寄存器(NFCONF)功能:用于对 Nand Flash 控制器的配置状态进行控制。

在地址空间中地址:0x4E000000,其中:

Bit15:Nand Flash 控制器使能位,置 0 代表禁止 Nand Flash 控制器,置 1 代表激活 Nand Flash 控制器;

要想访问 Nand Flash 芯片上存储空间,必须激活 Nand Flash 控制器。在复位后该位自动置 0,因此在初始化时

必须将该位置为 1。

Bit12:初始化 ECC 位,置 1 为初始化 ECC;置 0 为不初始化 ECC。

Bit11:Nand Flash 芯片存储空间使能位,置 0 代表可以对存储空间进行操作;置 1 代表禁止对存储空

间进行操作。在复位后,该位自动为 1。

Bit10-8:TACLS 位。根据此设定 CLE&ALE 的周期。TACLS 的值范围在 0-7 之间。

Bit6-4、2-0 分别为:TWRPH0、TWRPH1 位。设定写操作的访问周期。其值在 0-7 之间。

2. 命令寄存器(NFCMD)

功能:用于存放 Nand flash 芯片内设的操作命令。

在地址空间中地址:0x4E000004,其中:

Bit0-7:存放具体 Nand flash 芯片内设的命令值。其余位保留以后用。

3. 地址寄存器(NFADDR)

功能:用于存放用于对 Nand flash 芯片存储单元寻址的地址值。

在地址空间中地址:0x4E000008,其中:

Bit0-7:用于存放地址值。因为本款 Nand flash 芯片只有 I/O0-7 的地址/数据复用引脚且地址是四周

期每次 8 位送入的,所以这里只用到 8 位。其余位保留待用。

4. 数据寄存器(NFDATA)

功能:Nand flash 芯片所有内设命令执行后都会将其值放到该寄存器中。同时,读出、写入 Nand flash

存储空间的值也是放到该寄存器。

在地址空间中地址:0x4E00000C,其中:

Bit0-7:用于存放需要读出和写入的数据。其余位保留代用。

5. 状态寄存器(NFSTAT)

功能:用于检测 Nand flash 芯片上次对其存储空间的操作是否完成。

在地址空间中地址:0x4E000010,其中:

Bit0:置 0 表示 Nand flash 芯片正忙于上次对存储空间的操作;置 1 表示 Nand flash 芯片准备好接收新

的对存储空间操作的请求。

6. ECC 校验寄存器(NFECC)

功能:ECC 校验寄存器

在地址空间中地址:0x4E000014,其中:

Bit0-Bit7: ECC0

Bit8-Bit15: ECC1

Bit16-Bit23: ECC2

1.4 Nand Flash 控制器中的硬件 ECC 介绍

1.4.1 ECC 产生方法

ECC 是用于对存储器之间传送数据正确进行校验的一种算法,分硬件 ECC 和软件 ECC 算法两种,在

S3C2410 的 Nand Flash 控制器中实现了由硬件电路(ECC 生成器)实现的硬件 ECC。1.4.2 ECC 生成器工作过程

当写入数据到 Nand flash 存储空间时, ECC 生成器会在写入数据完毕后自动生成 ECC 码,将其放入到

ECC0-ECC2。当读出数据时 Nand Flash 同样会在读数据完毕后,自动生成 ECC 码将其放到 ECC0-ECC2 当

中。

1.4.3 ECC 的运用

当写入数据时,可以在每页写完数据后将产生的 ECC 码放入到 OOB 指定的位置(Byte 6)去,这样就完成了

ECC 码的存储。这样当读出该页数据时,将所需数据以及整个 OOB 读出,然后将指定位置的 ECC 码与读出数

据后在 ECC0-ECC1 的实际产生的 ECC 码进行对比,如果相等则读出正确,若不相等则读取错误需要进行重

读。

2 在 ADS 下 flash 烧写程序

2.1 ADS 下 flash 烧写程序原理及结构

基本原理:在 windows 环境下借助 ADS 仿真器将在 SDRAM 中的一段存储区域中的数据写到 Nand flash 存

储空间中。烧写程序在纵向上分三层完成:

第一层: 主烧写函数(完成将在 SDRAM 中的一段存储区域中的数据写到 Nand flash 存储空间中);

第二层: 为第一层主烧写函数提供支持的对 Nand flash 进行操作的页读、写,块擦除等函数;

第三层:为第二层提供具体 Nand flash 控制器中对特殊功能寄存器进行操作的核心函数,该层也是真正的

将数据能够在 SDRAM 和 Nand flash 之间实现传送的函数。

下面对其三层进行分述:

2.2 第三层实现说明

2.1.1 特殊功能寄存器定义

#define rNFCONF (*(volatile unsigned int *)0x4e000000)

#define rNFCMD (*(volatile unsigned char *)0x4e000004)

#define rNFADDR (*(volatile unsigned char *)0x4e000008)

#define rNFDATA (*(volatile unsigned char *)0x4e00000c)

#define rNFSTAT (*(volatile unsigned int *)0x4e000010)

#define rNFECC (*(volatile unsigned int *)0x4e000014)

#define rNFECC0 (*(volatile unsigned char *)0x4e000014)

#define rNFECC1 (*(volatile unsigned char *)0x4e000015)

#define rNFECC2 (*(volatile unsigned char *)0x4e000016)

2.1.2 操作的函数实现

1. 发送命令

#define NF_CMD(cmd) {rNFCMD=cmd;}

2. 写入地址

#define NF_ADDR(addr) {rNFADDR=addr;}

3. Nand Flash 芯片选中

#define NF_nFCE_L()

{rNFCONF&=~(1<<11);}

4. Nand Flash 芯片不选中

#define NF_nFCE_H()

{rNFCONF|=(1<<11);}

5. 初始化 ECC

#define NF_RSTECC() {rNFCONF|=(1<<12);}

6. 读数据#define NF_RDDATA() (rNFDATA)

7. 写数据

#define NF_WRDATA(data) {rNFDATA=data;}

8. 获取 Nand Flash 芯片状态

#define NF_WAITRB() {while(!(rNFSTAT&(1<<0)));}

0/假: 表示 Nand Flash 芯片忙状态

1/真:表示 Nand Flash 已经准备好

2.3 第二层实现说明

2.3.1 Nand Flash 初始化

void NF_Init(void)

{

/* 设置 Nand Flash 配置寄存器, 每一位的取值见 1.3 节 */

rNFCONF=(1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);

/* 复位外部 Nand Flash 芯片 */

NF_Reset();

}

2.3.2 Nand flash 复位

static void NF_Reset(void)

{

int i;

NF_nFCE_L(); /* 片选 Nand Flash 芯片*/

NF_CMD(0xFF);

/* 复位命令 */

for(i=0;i<10;i++); /* 等待 tWB = 100ns. */

NF_WAITRB(); /* wait 200~500us; */

NF_nFCE_H(); /* 取消 Nand Flash 选中*/

}

2.3.3 获取 Nand flash ID

返回值为 Nand flash 芯片的 ID 号

unsigned short NF_CheckId(void)

{

int i;

unsigned short id;

NF_nFCE_L(); /* 片选 Nand Flash 芯片*/

NF_CMD(0x90); /* 发送读 ID 命令到 Nand Flash 芯片 */

NF_ADDR(0x0); /* 指定地址 0x0,芯片手册要求 */

for(i=0;i<10;i++); /* 等待 tWB = 100ns. */

id=NF_RDDATA()<<8; /* 厂商 ID(K9S1208V:0xec) */

id|=NF_RDDATA(); /* 设备 ID(K9S1208V:0x76) */

NF_nFCE_H(); /* 取消 Nand Flash 选中*/

return id;

}2.3.4 Nand flash 写入

以页为单位写入.

参数说明:block 块号

page 页号

buffer 指向内存中待写入 Nand flash 中的数据起始位置

返回值: 0:写错误

1:写成功

static int NF_WritePage(unsigned int block, unsigned int page, unsigned char *buffer)

{

int i;

unsigned int blockPage = (block<<5)+page;

unsigned char *bufPt = buffer;

NF_RSTECC(); /* 初始化 ECC */

NF_nFCE_L(); /* 片选 Nand Flash 芯片*/

NF_CMD(0x0); /* 从 A 区开始写 */

NF_CMD(0x80); /* 写第一条命令 */

NF_ADDR(0); /* A0~A7 位(Column Address) */

NF_ADDR(blockPage&0xff); /* A9-A16, (Page Address) */

NF_ADDR((blockPage>>8)&0xff); /* A17-A24, (Page Address) */

NF_ADDR((blockPage>>16)&0xff); /* A25, (Page Address) */

for(i=0;i<512;i++)

{

NF_WRDATA(*bufPt++);

/* 写一个页 512 字节到 Nand Flash 芯片 */

}

/*

* OOB 一共 16 Bytes, 每一个字节存放什么由程序员自己定义, 通常,

* 我们在 Byte0-Byte2 存 ECC 检验码. Byte6 存放坏块标志.

*/

seBuf[0]=rNFECC0; /* 读取 ECC 检验码 0 */

seBuf[1]=rNFECC1; /* 读取 ECC 检验码 1 */

seBuf[2]=rNFECC2; /* 读取 ECC 检验码 2 */

seBuf[5]=0xff;

/* 非坏块标志 */

for(i=0;i<16;i++)

{

NF_WRDATA(seBuf[i]); /* 写该页的 OOB 数据块 */

}

NF_CMD(0x10); /* 结束写命令 */

/* 等待 Nand Flash 处于准备状态 */

for(i=0;i<10;i++);

NF_WAITRB();

/* 发送读状态命令给 Nand Flash */

NF_CMD(0x70);

for(i=0;i<3;i++);

if (NF_RDDATA()&0x1)

{ /*如果写有错, 则标示为坏块 */

NF_nFCE_H(); /* 取消 Nand Flash 选中*/

NF_MarkBadBlock(block);

return 0;

} else { /* 正常退出 */

NF_nFCE_H(); /* 取消 Nand Flash 选中*/

return 1;

}

}

2.3.5 Nand flash 读取

参数说明:block:块号

page:页号

buffer:指向将要读取到内存中的起始位置

返回值:1:读成功

0:读失败

static int NF_ReadPage(unsigned int block, unsigned int page, unsigned char *buffer)

{

int i;

unsigned int blockPage;

unsigned char ecc0, ecc1, ecc2;

unsigned char *bufPt=buffer;

unsigned char se[16];

page=page&0x1f;

blockPage=(block<<5)+page;

NF_RSTECC(); /* 初始化 ECC */

NF_nFCE_L(); /* 片选 Nand Flash 芯片*/

NF_CMD(0x00); /* 从 A 区开始读 */

NF_ADDR(0); /* A0~A7 位(Column Address) */

NF_ADDR(blockPage&0xff); /* A9-A16, (Page Address) */

NF_ADDR((blockPage>>8)&0xff); /* A17-A24, (Page Address) */

NF_ADDR((blockPage>>16)&0xff); /* A25, (Page Address) */

/* 等待 Nand Flash 处于再准备状态 */

for(i=0;i<10;i++);

NF_WAITRB(); /*等待 tR(max 12us) */

/* 读整个页, 512 字节 */

for(i=0;i<512;i++)

{

*bufPt++=NF_RDDATA();

}

/* 读取 ECC 码 */

ecc0=rNFECC0;

ecc1=rNFECC1;

ecc2=rNFECC2;

/* 读取该页的 OOB 块 */

for(i=0;i<16;i++)

{

se[i]=NF_RDDATA();

}

NF_nFCE_H(); /* 取消 Nand Flash 选中*/

/* 校验 ECC 码, 并返回 */

if(ecc0==se[0] && ecc1==se[1] && ecc2==se[2])

return 1;

else

return 0;

}

2.3.6 Nand flash 标记坏块

如果是坏块, 通过写 OOB 块的 Byte6 把该块标记为坏块。

参数说明:block 块号

返回值:1:ok,成功完成标记。

0:表示写 OOB 块正确.

static int NF_MarkBadBlock(unsigned int block)

{

int i;

unsigned int blockPage=(block<<5);

seBuf[0]=0xff;

seBuf[1]=0xff;

seBuf[2]=0xff;

seBuf[5]=0x44; /* 设置坏块标记 */

NF_nFCE_L(); /* 片选 Nand Flash 芯片*/

NF_CMD(0x50); /* 从 C 区开始写 */

NF_CMD(0x80); /* 发送编程命令, 让 Nand Flash 处理写状态 */

NF_ADDR(0x0); /* A0~A7 位(Column Address) */

NF_ADDR(blockPage&0xff); /* A9-A16, (Page Address) */

NF_ADDR((blockPage>>8)&0xff); /* A17-A24, (Page Address) */

NF_ADDR((blockPage>>16)&0xff); /* A25, (Page Address) */

/* 写 OOB 数据块 */

for(i=0;i<16;i++)

{

NF_WRDATA(seBuf[i]);

}

NF_CMD(0x10); /* 结束写命令 */

/* 等待 NandFlash 准备好 */

for(i=0;i<10;i++); /* tWB = 100ns. */

NF_WAITRB(); /*读 NandFlash 的写状态 */

NF_CMD(0x70);

for(i=0;i<3;i++); /* twhr=60ns */

if (NF_RDDATA()&0x1)

{

NF_nFCE_H(); /* 取消 Nand Flash 选中*/

return 0;

} else {

NF_nFCE_H(); /* 取消 Nand Flash 选中*/

}

return 1;

}

2.3.7 Nand Flash 检查坏块

检查指定块是否是坏块.

参数说明:block:块号

返回值:1:指定块是坏块

0:指定块不是坏块。

static int NF_IsBadBlock(U32 block)

{

int i;

unsigned int blockPage;

U8 data;

blockPage=(block<<5);

NF_nFCE_L(); /* 片选 Nand Flash 芯片*/

NF_CMD(0x50); /* Read OOB 数据块 */

NF_ADDR(517&0xf); /* A0~A7 位(Column Address) */

NF_ADDR(blockPage&0xff); /* A9-A16, (Page Address) */

NF_ADDR((blockPage>>8)&0xff); /* A17-A24, (Page Address) */

NF_ADDR((blockPage>>16)&0xff); /* A25, (Page Address) */

/* 等待 NandFlash 准备好 */

for(i=0;i<10;i++);

/* wait tWB(100ns) */

NF_WAITRB();

/* 读取读出值 */

data=NF_RDDATA();

NF_nFCE_H(); /* 取消 Nand Flash 选中*/

/* 如果 data 不为 0xff 时, 表示该块是坏块 */

if(data != 0xff)

return 1;

else

return 0;

}

2.3.8 擦除指定块中数据

参数说明:block 块号

返回值:0:擦除错误。(若是坏块直接返回 0;若擦除出现错误则标记为坏块然后返回 0) 1:成功擦除。

static int NF_EraseBlock(unsigned int block)

{

unsigned int blockPage=(block<<5);

int i;

/* 如果该块是坏块, 则返回 */

if(NF_IsBadBlock(block))

return 0;

NF_nFCE_L(); /* 片选 Nand Flash 芯片*/

NF_CMD(0x60); /* 设置擦写模式 */

NF_ADDR(blockPage&0xff); /* A9-A16, (Page Address) , 是基于块擦*/

NF_ADDR((blockPage>>8)&0xff); /* A17-A24, (Page Address) */

NF_ADDR((blockPage>>16)&0xff); /* A25, (Page Address) */

NF_CMD(0xd0); /* 发送擦写命令, 开始擦写 */

/* 等待 NandFlash 准备好 */

for(i=0;i<10;i++); /* tWB(100ns) */

NF_WAITRB();

/* 读取操作状态 */

NF_CMD(0x70);

if (NF_RDDATA()&0x1)

{

NF_nFCE_H(); /* 取消 Nand Flash 选中*/

NF_MarkBadBlock(block); /* 标记为坏块 */

return 0;

} else {

NF_nFCE_H(); /* 取消 Nand Flash 选中*/

return 1;

}

}

2.4 第一层的实现

2.4.1 NandFlash 烧写主函数说明

参数说明: block 块号

srcAddress SDRAM 中数据起始地址

fileSize 要烧写的数据长度

返回值: 无

void K9S1208_Program(unsigned int block, unsigned int srcAddress, unsigned int fileSize)

{

int i;

int programError=0;

U32 blockIndex;

U8 *srcPt, *saveSrcPt;

srcPt=(U8 *)srcAddress; /* 文件起始地址 */

blockIndex = block; /* 块号 */ while(1)

{

saveSrcPt=srcPt;

/* 如果当前块是坏块, 跳过当前块 */

if(NF_IsBadBlock(blockIndex))

{

blockIndex++; /* 到下一个块 */

continue;

}

/* 在写之前, 必须先擦除, 如果擦除不成功, 跳过当前块 */

if(!NF_EraseBlock(blockIndex))

{

blockIndex++; /* 到下一个块 */

continue;

}

/* 写一个块, 一块有 32 页 */

for(i=0;i<32;i++)

{

/* 写入一个页, 如果出错, 停止写当前块 */

if(!NF_WritePage(blockIndex,i,srcPt))

{

programError=1;

break;

}

/* 如果操作正常, 文件的写位置加上 1 页偏移,到下一页的起始位置 */

srcPt+=512;

/* 如果写地址没有超过文件长度, 继续; 超出则终止写 */

if((U32)srcPt>=(srcAddress+fileSize))

break;

}

/* 如果写一个块时, 其中某一页写失败, 则把写地址恢复写该块之前, 并跳过当前块 */

if(programError==1)

{

blockIndex++;

srcPt=saveSrcPt;

programError=0;

continue;

}

/* 如果写地址没有超过文件长度, 继续; 超出则终止写 */

if((U32)srcPt >= (srcAddress+fileSize))

break;

/* 如果正常写成功, 继续写下一个块 */

blockIndex++;

}

}


相关推荐

使用再生龙工具远程克隆Linux服务器

大家好,之前给大家介绍一个一款可以用来备份还原、远程克隆、P2V、V2V的工具--再生龙,今天就来给大家演示如何用该工具来远程克隆一台linux服务器。使用此方法,可以将一台物理服务器远程克隆到虚拟...

Linux 下用 SSH 登录远程服务器后把远程服务器文件传本地电脑

在Linux下,使用SSH命令登录远程服务器后,可以使用scp命令将远程服务器上的文件复制到本地电脑。以下是scp命令的基本用法:scp[用户名]@[远程服务器地址]:[远程文件路径][本地存放路...

一文掌握怎么利用Shell+Python实现Linux系统数据异地备份程序

简介:在当今的信息化时代,数据安全已成为企业和个人运维的重中之重。无论是服务器宕机、硬盘损坏,还是遭遇勒索病毒,数据丢失都可能带来巨大损失。为了最大程度保障数据安全,异地备份成为了最佳实践之一。本文将...

如何在Linux上搭建本地Docker Registry并实现远程连接

在Linux上搭建本地DockerRegistry并实现远程连接,可以按照以下步骤操作:一、安装Docker确保Linux系统上已经安装了Docker。如果尚未安装,可以使用以下命令进行安装(以Ub...

服务器连接方法教程(服务器地址怎么连接)

连接服务器的方式多种多样,具体取决于服务器的类型、操作系统以及你的使用需求。以下是几种常见的服务器连接方法,包含详细步骤和注意事项:一、远程桌面连接(适用于Windows服务器)适用场景:需要图形...

自动化测试学习:使用python库Paramiko实现远程服务器上传和下载

前言测试过程中经常会遇到需要将本地的文件上传到远程服务器上,或者需要将服务器上的文件拉到本地进行操作,以前安静经常会用到xftp工具。今天安静介绍一种python库Paramiko,可以帮助我们通过代...

手把手教你安装、远程连接Ubuntu 22.04

Ubuntu分为桌面版和服务器版本,我们选择服务器版本1下载Ubuntu22.04Ubuntu22.04下载地址:https://releases.ubuntu.com/22.04/ubuntu...

Windows服务器怎么连接?远程连接服务器命令

服务器操作系统可以实现对计算机硬件与软件的直接控制和管理协调,任何计算机的运行离不开操作系统,服务器也一样,服务器操作系统主要分为四大流派:WindowsServer、Netware、Unix和Li...

如何使用JuiceSSH实现手机端远程连接Linux服务器

在当今数字化时代,远程连接到服务器成为了许多人工作和生活中的必需品。JuiceSSH是一款比较强大的Android应用程序,它可以让您在手机上轻松地远程连接到Linux服务器。下面简单的向您介绍如何使...

本地电脑如何远程连接服务器(电脑如何远程桌面连接服务器)

下面就来说说如何远程登录服务器。服务器一般有两大类系统,一种是windows系统,一种是Linux系统。下面以Windows系统为例1、Windows系统有自带的登录系统,点击“运行”(或者windo...

如何用CHAT配置linux的远程连接?(chattr linux)

问CHAT:配置linux的远程连接1.下载ssh2.启动ssh服务3.查看ssh服务状态4.设置ssh服务开机自启动5.设置windows的cmd下ssh6.通过cmd的ssh命令远程到...

服务器怎么远程连接控制(服务器远程桌面连接设置方法)

我是艾西,还是有很多小白同学问我服务器怎么远程连接。那么今天我们重点来教教大家如何用电脑远程服务器配上图文教程,让不懂的新手小白一看就会,分分钟上手教程远程服务器需要一台电脑俗称“PC”就是我们自己平...

如何远程管理Linux服务器(linux远程登录管理)

在当今数字化的时代,Linux服务器凭借其稳定性和高效性,成为众多企业和开发者的首选。然而,很多时候我们无法直接在服务器前操作,这就需要掌握远程管理Linux服务器的技巧啦。别担心,今天就来给大家分享...

Linux系统无法启动?别慌!这可能是全网最全的故障排查攻略

当Linux系统罢工时,盲目重装只会浪费时间!本文整理8种常见故障的解决方案,涵盖从引导修复到硬件检测全流程,建议收藏备用。一、引导阶段故障排查1.GRUB引导丢失现象:黑屏显示"grub&...

Linux进程管理(linux进程管理实验报告)

原作者:Linux教程,原文「链接」:https://mp.weixin.qq.com/s/39rQMl3V2Egot9cZ14NCLg【获得原作者转载授权】每个计算机系统都包含一个核心软件集合,即操...