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:
parent
03e268f710
commit
aa387e176d
@ -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__ */
|
11
include/io.h
11
include/io.h
@ -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__ */
|
25
src/fat12.c
25
src/fat12.c
@ -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;
|
||||||
}
|
}
|
41
src/io.c
41
src/io.c
@ -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
|
15
src/mkfat.c
15
src/mkfat.c
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user