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> #include <stdint.h>
struct pang_io;
struct fat12_partition; struct fat12_partition;
struct fat12_dirent { struct fat12_dirent {
char filename[256]; 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); void fat12_set_cluster(void *fat, uint32_t cluster, uint32_t value);
uint32_t fat12_get_cluster(void *fat, uint32_t cluster); uint32_t fat12_get_cluster(void *fat, uint32_t cluster);
int fat12_defrag(int fd); int fat12_defrag(struct pang_io *io);
int fat12_mkfs(int fd, uint32_t bytes); int fat12_mkfs(struct pang_io *io, uint32_t bytes);
#endif /* PANG_O_LIN_FAT12_H__ */ #endif /* PANG_O_LIN_FAT12_H__ */

View File

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

View File

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

View File

@ -4,24 +4,41 @@
#include "io.h" #include "io.h"
#ifdef unix #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) { ssize_t pang_read(struct pang_io *io, off_t offset, void *buf, size_t count) {
return read(fd, buf, 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) { struct pang_io *pang_open(const char *pathname) {
return lseek(fd, offset, whence); 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) { int pang_close(struct pang_io **io) {
return open(pathname, flags); if (!io)
} return -1;
if (!*io)
int pang_close(int fd) { return -1;
return close(fd); int ret = close((*io)->fd);
free(*io);
*io = NULL;
return ret;
} }
#endif #endif

View File

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

View File

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

View File

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