pang-io: rework api for memory-mapped io

On real hardwareit will use memory-mapped io.  Rework pang-io so that it
more closely aligns with this paradigm.

Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
Sean Cross 2019-06-12 18:22:12 +08:00
parent 03e268f710
commit aa387e176d
7 changed files with 70 additions and 49 deletions

View File

@ -3,6 +3,7 @@
#include <stdint.h>
struct pang_io;
struct fat12_partition;
struct fat12_dirent {
char filename[256];
@ -29,7 +30,7 @@ uint32_t fat12_read_u32(void *ptr);
void fat12_set_cluster(void *fat, uint32_t cluster, uint32_t value);
uint32_t fat12_get_cluster(void *fat, uint32_t cluster);
int fat12_defrag(int fd);
int fat12_mkfs(int fd, uint32_t bytes);
int fat12_defrag(struct pang_io *io);
int fat12_mkfs(struct pang_io *io, uint32_t bytes);
#endif /* PANG_O_LIN_FAT12_H__ */

View File

@ -11,10 +11,11 @@
#include <unistd.h>
#endif
ssize_t pang_write(int fd, const void *buf, size_t count);
ssize_t pang_read(int fd, void *buf, size_t count);
off_t pang_seek(int fd, off_t offset, int whence);
int pang_open(const char *pathname, int flags);
int pang_close(int fd);
struct pang_io;
ssize_t pang_write(struct pang_io *io, off_t offset, const void *buf, size_t count);
ssize_t pang_read(struct pang_io *io, off_t offset, void *buf, size_t count);
struct pang_io *pang_open(const char *pathname);
int pang_close(struct pang_io **io);
#endif /* PANG_O_LIN_IO_H__ */

View File

@ -5,7 +5,7 @@
#include <stdio.h>
struct fat12_partition {
int fd;
struct pang_io *io;
// Number of bytes in a sector (512)
uint32_t sector_size;
@ -105,18 +105,15 @@ int fat12_open(struct fat12_partition *part, const char *filename) {
if (!part)
return -1;
if (part->fd > 0)
if (part->io)
return -1;
part->fd = pang_open(filename, O_RDWR);
if (part->fd == -1) {
part->fd = 0;
part->io = pang_open(filename);
if (!part->io)
return -1;
}
if (pang_read(part->fd, part->sector_buffer, sizeof(part->sector_buffer)) != sizeof(part->sector_buffer)) {
if (pang_read(part->io, 0, part->sector_buffer, sizeof(part->sector_buffer)) != sizeof(part->sector_buffer))
return -1;
}
part->sector_size = fat12_read_u16(part->sector_buffer + 0x0b);
@ -165,8 +162,7 @@ static int fat12_ls_foreach_sector(struct fat12_partition *part, uint32_t sector
struct fat12_dirent dirent;
uint8_t buf[part->sector_size];
uint32_t offset;
pang_seek(part->fd, sector * part->sector_size, SEEK_SET);
pang_read(part->fd, buf, sizeof(buf));
pang_read(part->io, sector * part->sector_size, buf, sizeof(buf));
for (offset = 0; offset < count; offset++) {
struct fat_directory_entry *entry = &((struct fat_directory_entry *)buf)[offset];
@ -211,14 +207,10 @@ int fat12_close(struct fat12_partition *part) {
if (!part)
return -1;
if (part->fd <= 0)
return -1;
if (-1 == pang_close(part->fd)) {
if (-1 == pang_close(&part->io)) {
return -1;
}
part->fd = 0;
return 0;
}
@ -229,6 +221,9 @@ void fat12_free(struct fat12_partition **part) {
if (!*part)
return;
if ((*part)->io)
fat12_close(*part);
free(*part);
*part = NULL;
}

View File

@ -4,24 +4,41 @@
#include "io.h"
#ifdef unix
ssize_t pang_write(int fd, const void *buf, size_t count) {
return write(fd, buf, count);
struct pang_io {
int fd;
};
ssize_t pang_write(struct pang_io *io, off_t offset, const void *buf, size_t count) {
if (-1 == lseek(io->fd, offset, SEEK_SET))
return -1;
return write(io->fd, buf, count);
}
ssize_t pang_read(int fd, void *buf, size_t count) {
return read(fd, buf, count);
ssize_t pang_read(struct pang_io *io, off_t offset, void *buf, size_t count) {
if (-1 == lseek(io->fd, offset, SEEK_SET))
return -1;
return read(io->fd, buf, count);
}
off_t pang_seek(int fd, off_t offset, int whence) {
return lseek(fd, offset, whence);
struct pang_io *pang_open(const char *pathname) {
int fd = open(pathname, O_RDWR | O_TRUNC | O_CREAT, 0777);
if (-1 == fd)
return NULL;
struct pang_io *io = malloc(sizeof(struct pang_io));
io->fd = fd;
return io;
}
int pang_open(const char *pathname, int flags) {
return open(pathname, flags);
}
int pang_close(int fd) {
return close(fd);
int pang_close(struct pang_io **io) {
if (!io)
return -1;
if (!*io)
return -1;
int ret = close((*io)->fd);
free(*io);
*io = NULL;
return ret;
}
#endif

View File

@ -12,8 +12,9 @@
// with length _bytes_.
// It will define a root directory size and padding size so that the file sectors
// end up on 4096-byte boundaries.
int fat12_mkfs(int fd, uint32_t bytes) {
int fat12_mkfs(struct pang_io *io, uint32_t bytes) {
uint8_t mbr[512];
off_t offset = 0;
const uint32_t sector_size = 512;
uint32_t cluster_size = 4096 / sector_size; // 4 kiB cluster sizes match flash erase block size
if (bytes > 16000000) {
@ -118,9 +119,10 @@ int fat12_mkfs(int fd, uint32_t bytes) {
fat12_write_u8(mbr + 0xff, 0xaa);
// Write MBR to disk
if (pang_write(fd, mbr, sizeof(mbr)) != sizeof(mbr)) {
if (pang_write(io, offset, mbr, sizeof(mbr)) != sizeof(mbr)) {
return -1;
}
offset += sector_size;
memset(mbr, 0, sizeof(mbr));
@ -131,25 +133,28 @@ int fat12_mkfs(int fd, uint32_t bytes) {
// Root directory is only one cluster
// fat12_set_cluster(mbr, 2, 0xfff);
if (pang_write(fd, mbr, sizeof(mbr)) != sizeof(mbr)) {
if (pang_write(io, offset, mbr, sizeof(mbr)) != sizeof(mbr)) {
return -1;
}
offset += sector_size;
// Fill in the rest of the FAT
uint32_t fat_sector;
memset(mbr, 0, sizeof(mbr));
for (fat_sector = 1; fat_sector < fat_size_sectors; fat_sector++) {
if (pang_write(fd, mbr, sizeof(mbr)) != sizeof(mbr)) {
if (pang_write(io, offset, mbr, sizeof(mbr)) != sizeof(mbr)) {
return -1;
}
offset += sector_size;
}
// Fill in the root directory
uint32_t root_directory_sector;
for (root_directory_sector = 0; root_directory_sector < cluster_size; root_directory_sector++) {
if (pang_write(fd, mbr, sizeof(mbr)) != sizeof(mbr)) {
if (pang_write(io, offset, mbr, sizeof(mbr)) != sizeof(mbr)) {
return -1;
}
offset += sector_size;
}
return 0;

View File

@ -7,21 +7,22 @@
#include <string.h>
#include "fat12.h"
#include "io.h"
static int make_image(const char *name, uint32_t size) {
int fd = open(name, O_WRONLY | O_CREAT, 0777);
if (-1 == fd) {
struct pang_io *io = pang_open(name);
if (!io) {
fprintf(stderr, "couldn't open %s: %s\n", name, strerror(errno));
return 1;
}
if (-1 == fat12_mkfs(fd, size)) {
if (-1 == fat12_mkfs(io, size)) {
fprintf(stderr, "couldn't make fat12 on %s: %s\n", name, strerror(errno));
close(fd);
pang_close(&io);
return 1;
}
close(fd);
pang_close(&io);
return 0;
}

View File

@ -7,21 +7,22 @@
#include <string.h>
#include "fat12.h"
#include "io.h"
static int make_image(const char *name, uint32_t size) {
int fd = open(name, O_WRONLY | O_CREAT, 0777);
if (-1 == fd) {
struct pang_io *io = pang_open(name);
if (!io) {
fprintf(stderr, "couldn't open %s: %s\n", name, strerror(errno));
return 1;
}
if (-1 == fat12_mkfs(fd, size)) {
if (-1 == fat12_mkfs(io, size)) {
fprintf(stderr, "couldn't make fat12 on %s: %s\n", name, strerror(errno));
close(fd);
pang_close(&io);
return 1;
}
close(fd);
pang_close(&io);
return 0;
}