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 */