diff --git a/arm_virt/README.md b/arm_virt/README.md
index ac10024d3d6884b23688de8232b1a225f9934d3a..ca53e22748f42a2b2a9a8f1c14bb0a4b78846323 100755
--- a/arm_virt/README.md
+++ b/arm_virt/README.md
@@ -103,3 +103,5 @@ Note: OHOS build target name `qemu_arm_virt_ca7` is derived from the above menti
#### 6. Usage examples
- [passing debug arguments from command line](example.md#sectiondebug)
+
+- [passing files through FAT image](example.md#sectionfatfs)
diff --git a/arm_virt/README_zh.md b/arm_virt/README_zh.md
index edcbeada2f4bc6453349f39bcb62d15a268b988b..acb05cd4ad0b627f002fd39281afa7716ae45c19 100755
--- a/arm_virt/README_zh.md
+++ b/arm_virt/README_zh.md
@@ -95,3 +95,5 @@ Explanation for our system configuration:
## 6. 用法示例
- [向内核传递调试参数](example.md#sectiondebug)
+
+- [用FAT映像传递文件](example.md#sectionfatfs)
diff --git a/arm_virt/example.md b/arm_virt/example.md
index 166b0f40f9cb16932cd8be14321334d7114211da..699365f143900ff9bc63cc2487ae59353845c6d3 100644
--- a/arm_virt/example.md
+++ b/arm_virt/example.md
@@ -1,4 +1,5 @@
## 向内核传递调试参数
+---
### QEMU命令行参数:
@@ -39,3 +40,42 @@
qemu-system-arm ...(正常运行参数) \
-fw_cfg name=opt/d,string="qsz=0x400 file='test.txt"
```
+
+## 用FAT映像传递文件
+---
+
+利用arm virt的第二个CFI flash设备,可以加载FAT格式的映像盘。因为FAT映像制作、挂载、存储文件均比较简单,可由此在宿主机和虚拟机间方便地传递文件。
+
+1. 准备FAT映像
+```
+dd if=/dev/zero of=fat.img bs=64M count=1
+sudo losetup /dev/loop0 fat.img
+sudo fdisk /dev/loop0 # 磁盘分区选择MBR格式, FAT16或FAT32
+sudo losetup -o 1048576 /dev/loop1 /dev/loop0 # 这里用第一个主分区示例
+sudo mkfs.vfat /dev/loop1
+```
+
+2. 在虚拟机中挂载
+```
+qemu-system-arm ...(正常运行参数) \
+ -drive if=pflash,file=fat.img,format=raw
+
+OHOS # mount /dev/cfiblkp0 some_dir vfat
+```
+
+**注意**:新加的drive参数要在原drive参数的后面。
+
+3. 在宿主机中挂载
+```
+sudo losetup /dev/loop0 fat.img
+sudo losetup -o 1048576 /dev/loop1 /dev/loop0
+sudo mount /dev/loop1 some_dir
+```
+
+4. 缷载
+```
+sudo umount some_dir
+
+sudo losetup -d /dev/loop1 # 宿主机时
+sudo losetup -d /dev/loop0 # 宿主机时
+```
diff --git a/arm_virt/liteos_a/config/cfiflash/cfi_config.hcs b/arm_virt/liteos_a/config/cfiflash/cfi_config.hcs
index 1e0b30cd5691ae8b104997fcf53fa511d616b6e9..af8bcf7ae14ab7229dc1018acc914bd1bfe3b98e 100644
--- a/arm_virt/liteos_a/config/cfiflash/cfi_config.hcs
+++ b/arm_virt/liteos_a/config/cfiflash/cfi_config.hcs
@@ -2,7 +2,8 @@ root {
storage {
template cfi_flash_attr {
match_attr = "";
- pbase = 0x00000000; // slot0
+ pbase0 = 0x00000000; // slot0 jffs2
+ pbase1 = 0x04000000; // slot1 vfat
}
cfiflash0 :: cfi_flash_attr {
match_attr = "qemu_virt_cfi_0";
diff --git a/drivers/cfiflash/cfiflash.c b/drivers/cfiflash/cfiflash.c
index 9681e1ea0aac0e5f691507d037795cb8098cfe0d..c88da9c658fa1a3b37323101e01088eef1168942 100644
--- a/drivers/cfiflash/cfiflash.c
+++ b/drivers/cfiflash/cfiflash.c
@@ -20,17 +20,10 @@
*/
#include "user_copy.h"
+#include "disk.h"
+#include "cfiflash.h"
#include "cfiflash_internal.h"
-#ifdef __cplusplus
-#if __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-#endif /* __cplusplus */
-
-/* volatile disable compiler optimization */
-volatile uint32_t *g_cfiFlashBase;
-
#define BIT_SHIFT8 8
#define WORD_ALIGN 4
#define BYTE_WORD_SHIFT 2
@@ -60,28 +53,13 @@ static inline unsigned B2W(unsigned bytes)
return bytes >> BYTE_WORD_SHIFT;
}
-static inline uint8_t CfiFlashReadByte(unsigned byteOffset)
-{
- return ((uint8_t *)g_cfiFlashBase)[byteOffset];
-}
-
-static inline uint32_t CfiFlashReadWord(unsigned wordOffset)
-{
- return g_cfiFlashBase[wordOffset];
-}
-
-static inline void CfiFlashWriteWord(unsigned wordOffset, uint32_t value)
-{
- g_cfiFlashBase[wordOffset] = value;
-}
-
-static inline int CfiFlashQueryQRY()
+static inline int CfiFlashQueryQRY(uint8_t *p)
{
unsigned wordOffset = CFIFLASH_QUERY_QRY;
- if (CfiFlashReadByte(W2B(wordOffset++)) == 'Q') {
- if (CfiFlashReadByte(W2B(wordOffset++)) == 'R') {
- if (CfiFlashReadByte(W2B(wordOffset)) == 'Y') {
+ if (p[W2B(wordOffset++)] == 'Q') {
+ if (p[W2B(wordOffset++)] == 'R') {
+ if (p[W2B(wordOffset)] == 'Y') {
return 0;
}
}
@@ -89,34 +67,35 @@ static inline int CfiFlashQueryQRY()
return -1;
}
-static inline int CfiFlashQueryUint8(unsigned wordOffset, uint8_t expect)
+static inline int CfiFlashQueryUint8(unsigned wordOffset, uint8_t expect, uint8_t *p)
{
- if (CfiFlashReadByte(W2B(wordOffset)) != expect) {
+ if (p[W2B(wordOffset)] != expect) {
return -1;
}
return 0;
}
-static inline int CfiFlashQueryUint16(unsigned wordOffset, uint16_t expect)
+static inline int CfiFlashQueryUint16(unsigned wordOffset, uint16_t expect, uint8_t *p)
{
uint16_t v;
- v = (CfiFlashReadByte(W2B(wordOffset + 1)) << BIT_SHIFT8) +
- CfiFlashReadByte(W2B(wordOffset));
+ v = (p[W2B(wordOffset + 1)] << BIT_SHIFT8) + p[W2B(wordOffset)];
if (v != expect) {
return -1;
}
return 0;
}
-static inline int CfiFlashIsReady(unsigned wordOffset)
+static inline int CfiFlashIsReady(unsigned wordOffset, uint32_t *p)
{
- CfiFlashWriteWord(wordOffset, CFIFLASH_CMD_READ_STATUS);
- return CfiFlashReadWord(wordOffset) & CFIFLASH_STATUS_READY_MASK;
+ DSB;
+ p[wordOffset] = CFIFLASH_CMD_READ_STATUS;
+ DSB;
+ return p[wordOffset] & CFIFLASH_STATUS_READY_MASK;
}
/* all in word(4 bytes) measure */
-static void CfiFlashWriteBuf(unsigned wordOffset, const uint32_t *buffer, size_t words)
+static void CfiFlashWriteBuf(unsigned wordOffset, const uint32_t *buffer, size_t words, uint32_t *p)
{
unsigned i, blkAddr, wordCount;
@@ -127,60 +106,62 @@ static void CfiFlashWriteBuf(unsigned wordOffset, const uint32_t *buffer, size_t
while (words) {
/* command buffer-write begin to Erase Block address */
blkAddr = CfiFlashEraseBlkWordAddr(wordOffset);
- CfiFlashWriteWord(blkAddr, CFIFLASH_CMD_BUFWRITE);
+ p[blkAddr] = CFIFLASH_CMD_BUFWRITE;
/* write words count, 0-based */
- CfiFlashWriteWord(blkAddr, wordCount - 1);
+ DSB;
+ p[blkAddr] = wordCount - 1;
/* program word data to actual address */
for (i = 0; i < wordCount; i++, wordOffset++, buffer++) {
- CfiFlashWriteWord(wordOffset, *buffer);
+ p[wordOffset] = *buffer;
}
/* command buffer-write end to Erase Block address */
- CfiFlashWriteWord(blkAddr, CFIFLASH_CMD_CONFIRM);
- while (!CfiFlashIsReady(blkAddr)) { }
+ p[blkAddr] = CFIFLASH_CMD_CONFIRM;
+ while (!CfiFlashIsReady(blkAddr, p)) { }
words -= wordCount;
wordCount = (words >= CFIFLASH_PAGE_WORDS) ? CFIFLASH_PAGE_WORDS : words;
}
- CfiFlashWriteWord(0, CFIFLASH_CMD_CLEAR_STATUS);
+ p[0] = CFIFLASH_CMD_CLEAR_STATUS;
}
-static int CfiFlashQuery(void)
+static int CfiFlashQuery(uint8_t *p)
{
- CfiFlashWriteWord(CFIFLASH_QUERY_BASE, CFIFLASH_QUERY_CMD);
+ uint32_t *base = (uint32_t *)p;
+ base[CFIFLASH_QUERY_BASE] = CFIFLASH_QUERY_CMD;
- if (CfiFlashQueryQRY()) {
+ if (CfiFlashQueryQRY(p)) {
goto ERR_OUT;
}
- if (CfiFlashQueryUint16(CFIFLASH_QUERY_VENDOR, CFIFLASH_EXPECT_VENDOR)) {
+ if (CfiFlashQueryUint16(CFIFLASH_QUERY_VENDOR, CFIFLASH_EXPECT_VENDOR, p)) {
goto ERR_OUT;
}
- if (CfiFlashQueryUint8(CFIFLASH_QUERY_SIZE, CFIFLASH_ONE_BANK_BITS)) {
+ if (CfiFlashQueryUint8(CFIFLASH_QUERY_SIZE, CFIFLASH_ONE_BANK_BITS, p)) {
goto ERR_OUT;
}
- if (CfiFlashQueryUint16(CFIFLASH_QUERY_PAGE_BITS, CFIFLASH_EXPECT_PAGE_BITS)) {
+ if (CfiFlashQueryUint16(CFIFLASH_QUERY_PAGE_BITS, CFIFLASH_EXPECT_PAGE_BITS, p)) {
goto ERR_OUT;
}
- if (CfiFlashQueryUint8(CFIFLASH_QUERY_ERASE_REGION, CFIFLASH_EXPECT_ERASE_REGION)) {
+ if (CfiFlashQueryUint8(CFIFLASH_QUERY_ERASE_REGION, CFIFLASH_EXPECT_ERASE_REGION, p)) {
goto ERR_OUT;
}
- if (CfiFlashQueryUint16(CFIFLASH_QUERY_BLOCKS, CFIFLASH_EXPECT_BLOCKS)) {
+ if (CfiFlashQueryUint16(CFIFLASH_QUERY_BLOCKS, CFIFLASH_EXPECT_BLOCKS, p)) {
goto ERR_OUT;
}
- if (CfiFlashQueryUint16(CFIFLASH_QUERY_BLOCK_SIZE, CFIFLASH_EXPECT_BLOCK_SIZE)) {
+ if (CfiFlashQueryUint16(CFIFLASH_QUERY_BLOCK_SIZE, CFIFLASH_EXPECT_BLOCK_SIZE, p)) {
goto ERR_OUT;
}
- CfiFlashWriteWord(0, CFIFLASH_CMD_RESET);
+ base[0] = CFIFLASH_CMD_RESET;
return 0;
ERR_OUT:
@@ -188,16 +169,39 @@ ERR_OUT:
return -1;
}
-int CfiFlashInit(void)
+int CfiFlashInit(uint8_t *p)
{
+ struct MtdDev *slot = GetCfiMtdDev();
+
dprintf("[%s]CFI flash init start ...\n", __FUNCTION__);
- if (CfiFlashQuery()) {
+ if (CfiFlashQuery(p)) {
return -1;
}
+
+ /* slot 0 used as MTD device for jffs2 rootfs, slot 1 as block device */
+ if (slot->priv == NULL) {
+ slot->priv = p;
+ } else if (*(uint16_t *)&p[BS_SIG55AA] == BS_SIG55AA_VALUE) {
+ int id = los_alloc_diskid_byname(CFI_BLK_DRIVER);
+ (void)los_disk_init(CFI_BLK_DRIVER, GetCfiBlkOps(), p, id, NULL);
+ } else {
+ return 0;
+ }
+
dprintf("[%s]CFI flash init end ...\n", __FUNCTION__);
return 0;
}
+int CfiBlkOpen(struct Vnode *vnode)
+{
+ return 0;
+}
+
+int CfiBlkClose(struct Vnode *vnode)
+{
+ return 0;
+}
+
static ssize_t CfiPreRead(char *buffer, unsigned bytes, char **newbuf)
{
if (LOS_IsUserAddressRange((VADDR_T)buffer, bytes)) {
@@ -222,7 +226,7 @@ static ssize_t CfiPostRead(char *buffer, char *newbuf, unsigned bytes, ssize_t r
dprintf("[%s]LOS_ArchCopyToUser error\n", __FUNCTION__);
ret = -EFAULT;
}
-
+
if (LOS_MemFree(m_aucSysMem0, newbuf) != 0) {
dprintf("[%s]LOS_MemFree error\n", __FUNCTION__);
ret = -EFAULT;
@@ -236,6 +240,7 @@ ssize_t CfiBlkRead(struct Vnode *vnode, unsigned char *buffer,
{
unsigned int i, wordOffset, bytes;
uint32_t *p;
+ uint32_t *base = ((struct drv_data*)(vnode->data))->priv;
ssize_t ret;
bytes = CfiFlashSec2Bytes(nSectors);
@@ -246,7 +251,7 @@ ssize_t CfiBlkRead(struct Vnode *vnode, unsigned char *buffer,
}
for (i = 0; i < B2W(bytes); i++) {
- p[i] = CfiFlashReadWord(wordOffset + i);
+ p[i] = base[wordOffset + i];
}
ret = nSectors;
@@ -272,7 +277,7 @@ static ssize_t CfiPreWrite(const char *buffer, unsigned bytes, char **newbuf)
return -EFAULT;
} else {
*newbuf = (char*)buffer;
- }
+ }
return 0;
}
@@ -301,7 +306,7 @@ ssize_t CfiBlkWrite(struct Vnode *vnode, const unsigned char *buffer,
return ret;
}
- CfiFlashWriteBuf(wordOffset, (uint32_t *)p, B2W(bytes));
+ CfiFlashWriteBuf(wordOffset, (uint32_t *)p, B2W(bytes), ((struct drv_data*)(vnode->data))->priv);
ret = nSectors;
return CfiPostWrite((const char*)buffer, (char*)p, ret);
@@ -321,19 +326,21 @@ int CfiBlkGeometry(struct Vnode *vnode, struct geometry *geometry)
int CfiMtdErase(struct MtdDev *mtd, UINT64 start, UINT64 bytes, UINT64 *failAddr)
{
uint32_t blkAddr, count, i;
+ uint32_t *p = mtd->priv;
blkAddr = CfiFlashEraseBlkWordAddr(B2W(start));
count = (CfiFlashEraseBlkWordAddr(B2W(start + bytes - 1)) - blkAddr) / CFIFLASH_ERASEBLK_WORDS + 1;
for (i = 0; i < count; i++) {
- CfiFlashWriteWord(blkAddr, CFIFLASH_CMD_ERASE);
- CfiFlashWriteWord(blkAddr, CFIFLASH_CMD_CONFIRM);
- while (!CfiFlashIsReady(blkAddr)) { }
+ p[blkAddr] = CFIFLASH_CMD_ERASE;
+ DSB;
+ p[blkAddr] = CFIFLASH_CMD_CONFIRM;
+ while (!CfiFlashIsReady(blkAddr, p)) { }
blkAddr += CFIFLASH_ERASEBLK_WORDS;
}
- CfiFlashWriteWord(0, CFIFLASH_CMD_CLEAR_STATUS);
+ p[0] = CFIFLASH_CMD_CLEAR_STATUS;
return 0;
}
@@ -342,13 +349,14 @@ int CfiMtdRead(struct MtdDev *mtd, UINT64 start, UINT64 bytes, const char *buf)
UINT64 i;
char *p;
ssize_t ret;
+ uint8_t *base = mtd->priv;
if ((ret = CfiPreRead((char*)buf, bytes, &p))) {
return ret;
}
for (i = 0; i < bytes; i++) {
- p[i] = CfiFlashReadByte(start + i);
+ p[i] = base[start + i];
}
ret = (int)bytes;
@@ -369,14 +377,8 @@ int CfiMtdWrite(struct MtdDev *mtd, UINT64 start, UINT64 bytes, const char *buf)
return ret;
}
- CfiFlashWriteBuf((int)B2W(start), (uint32_t *)p, (size_t)B2W(bytes));
+ CfiFlashWriteBuf((int)B2W(start), (uint32_t *)p, (size_t)B2W(bytes), mtd->priv);
ret = (int)bytes;
return CfiPostWrite(buf, p, ret);
}
-
-#ifdef __cplusplus
-#if __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* __cplusplus */
diff --git a/drivers/cfiflash/cfiflash.h b/drivers/cfiflash/cfiflash.h
index 5d354f13823341d571453636b4d96cdd91116506..8477e4f55e309a197821fbf1af22df7be6808db6 100644
--- a/drivers/cfiflash/cfiflash.h
+++ b/drivers/cfiflash/cfiflash.h
@@ -18,13 +18,8 @@
#include "fs/driver.h"
#include "mtd_dev.h"
-#ifdef __cplusplus
-#if __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-#endif /* __cplusplus */
-
#define CFI_DRIVER "/dev/cfiflash"
+#define CFI_BLK_DRIVER "/dev/cfiblk"
#define FLASH_TYPE "cfi-flash"
#define CFIFLASH_CAPACITY (64 * 1024 * 1024)
@@ -38,10 +33,4 @@ extern "C" {
struct block_operations *GetCfiBlkOps(void);
struct MtdDev *GetCfiMtdDev(void);
-#ifdef __cplusplus
-#if __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* __cplusplus */
-
#endif
diff --git a/drivers/cfiflash/cfiflash_internal.h b/drivers/cfiflash/cfiflash_internal.h
index e28bb18a52973aa2a22091a29601d411d016866f..b9950990dc8dc385d276df0c1e9a4d8c081b303b 100644
--- a/drivers/cfiflash/cfiflash_internal.h
+++ b/drivers/cfiflash/cfiflash_internal.h
@@ -17,12 +17,6 @@
#include "cfiflash.h"
-#ifdef __cplusplus
-#if __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-#endif /* __cplusplus */
-
#define HDF_LOG_TAG cfi_flash_driver
#define CFIFLASH_ONE_BANK_BITS 25
@@ -59,9 +53,9 @@ extern "C" {
#define CFIFLASH_STATUS_READY_MASK 0x80
-extern volatile uint32_t *g_cfiFlashBase;
-
-int CfiFlashInit(void);
+int CfiFlashInit(uint8_t *p);
+int CfiBlkOpen(struct Vnode *vnode);
+int CfiBlkClose(struct Vnode *vnode);
ssize_t CfiBlkRead(struct Vnode *vnode, unsigned char *buffer,
unsigned long long start_sector, unsigned int nsectors);
ssize_t CfiBlkWrite(struct Vnode *vnode, const unsigned char *buffer,
@@ -72,10 +66,4 @@ int CfiMtdErase(struct MtdDev *mtd, UINT64 start, UINT64 bytes, UINT64 *failAddr
int CfiMtdRead(struct MtdDev *mtd, UINT64 start, UINT64 bytes, const char *buf);
int CfiMtdWrite(struct MtdDev *mtd, UINT64 start, UINT64 bytes, const char *buf);
-#ifdef __cplusplus
-#if __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* __cplusplus */
-
#endif
diff --git a/drivers/cfiflash/hdf_cfi.c b/drivers/cfiflash/hdf_cfi.c
index 0dc43d5e4f44e1a58f4ce26d17977a09344d280a..8a5478812f0f50cbd0bf46950a0565054ebf4c90 100644
--- a/drivers/cfiflash/hdf_cfi.c
+++ b/drivers/cfiflash/hdf_cfi.c
@@ -19,15 +19,9 @@
#include "los_vm_zone.h"
#include "cfiflash_internal.h"
-#ifdef __cplusplus
-#if __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-#endif /* __cplusplus */
-
static struct block_operations g_cfiBlkops = {
- NULL, /* int (*open)(struct Vnode *vnode); */
- NULL, /* int (*close)(struct Vnode *vnode); */
+ CfiBlkOpen,
+ CfiBlkClose,
CfiBlkRead,
CfiBlkWrite,
CfiBlkGeometry,
@@ -40,37 +34,44 @@ struct block_operations *GetCfiBlkOps()
return &g_cfiBlkops;
}
-static int HdfCfiMapInit(const struct DeviceResourceNode *node)
-{
- int ret;
- uint32_t pbase;
- struct DeviceResourceIface *p = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
-
- if ((ret = p->GetUint32(node, "pbase", &pbase, 0))) {
- HDF_LOGE("[%s]GetUint32 error:%d", __func__, ret);
- return HDF_FAILURE;
- }
-
- g_cfiFlashBase = (uint32_t *)IO_DEVICE_ADDR(pbase);
+static struct MtdDev g_cfiMtdDev = {
+ .priv = NULL,
+ .type = MTD_NORFLASH,
+ .size = CFIFLASH_CAPACITY,
+ .eraseSize = CFIFLASH_ERASEBLK_SIZE,
+ .erase = CfiMtdErase,
+ .read = CfiMtdRead,
+ .write = CfiMtdWrite,
+};
- return HDF_SUCCESS;
+struct MtdDev *GetCfiMtdDev()
+{
+ return &g_cfiMtdDev;
}
int HdfCfiDriverInit(struct HdfDeviceObject *deviceObject)
{
+ int ret;
+ uint32_t pbase;
+ struct DeviceResourceIface *p = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
+
if (deviceObject == NULL || deviceObject->property == NULL) {
HDF_LOGE("[%s]deviceObject or property is null", __func__);
return HDF_ERR_INVALID_PARAM;
}
- if (HdfCfiMapInit(deviceObject->property) != HDF_SUCCESS) {
+ if ((ret = p->GetUint32(deviceObject->property, "pbase0", &pbase, 0))) {
+ HDF_LOGE("[%s]GetUint32 error:%d", __func__, ret);
return HDF_FAILURE;
}
-
- if(CfiFlashInit()) {
+ if(CfiFlashInit((uint8_t *)IO_DEVICE_ADDR(pbase))) {
return HDF_ERR_NOT_SUPPORT;
}
+ if (p->GetUint32(deviceObject->property, "pbase1", &pbase, 0) == 0) {
+ (void)CfiFlashInit((uint8_t *)IO_DEVICE_ADDR(pbase));
+ }
+
return HDF_SUCCESS;
}
@@ -83,24 +84,3 @@ struct HdfDriverEntry g_cfiDriverEntry = {
};
HDF_INIT(g_cfiDriverEntry);
-
-static struct MtdDev g_cfiMtdDev = {
- .priv = NULL,
- .type = MTD_NORFLASH,
- .size = CFIFLASH_CAPACITY,
- .eraseSize = CFIFLASH_ERASEBLK_SIZE,
- .erase = CfiMtdErase,
- .read = CfiMtdRead,
- .write = CfiMtdWrite,
-};
-
-struct MtdDev *GetCfiMtdDev()
-{
- return &g_cfiMtdDev;
-}
-
-#ifdef __cplusplus
-#if __cplusplus
-}
-#endif /* __cplusplus */
-#endif /* __cplusplus */