mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-11-28 17:30:18 +00:00
cpio: add functions to create cpio images
Signed-off-by: Sven Peter <sven@svenpeter.dev>
This commit is contained in:
parent
e74b79dc2a
commit
cd4b563a31
3 changed files with 166 additions and 0 deletions
1
Makefile
1
Makefile
|
@ -39,6 +39,7 @@ OBJECTS := \
|
||||||
adt.o \
|
adt.o \
|
||||||
bootlogo_128.o bootlogo_256.o \
|
bootlogo_128.o bootlogo_256.o \
|
||||||
chickens.o \
|
chickens.o \
|
||||||
|
cpio.o \
|
||||||
dart.o \
|
dart.o \
|
||||||
exception.o exception_asm.o \
|
exception.o exception_asm.o \
|
||||||
fb.o font.o font_retina.o \
|
fb.o font.o font_retina.o \
|
||||||
|
|
147
src/cpio.c
Normal file
147
src/cpio.c
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
/* SPDX-License-Identifier: MIT */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "cpio.h"
|
||||||
|
#include "malloc.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#define CPIO_MAX_FILES 20
|
||||||
|
|
||||||
|
#define CPIO_MODE_DIR 0040755
|
||||||
|
#define CPIO_MODE_FILE 0100644
|
||||||
|
|
||||||
|
#define CPIO_HEADER_MAGIC "070701"
|
||||||
|
|
||||||
|
struct cpio_header {
|
||||||
|
char magic[6];
|
||||||
|
char inode[8];
|
||||||
|
char mode[8];
|
||||||
|
char uid[8];
|
||||||
|
char gid[8];
|
||||||
|
char nlink[8];
|
||||||
|
char mtime[8];
|
||||||
|
char filesize[8];
|
||||||
|
char devmajor[8];
|
||||||
|
char devminor[8];
|
||||||
|
char rdevmajor[8];
|
||||||
|
char rdevminor[8];
|
||||||
|
char namesize[8];
|
||||||
|
char checksum[8];
|
||||||
|
} PACKED;
|
||||||
|
|
||||||
|
struct cpio {
|
||||||
|
u32 n_files;
|
||||||
|
struct {
|
||||||
|
const u8 *ptr;
|
||||||
|
size_t sz;
|
||||||
|
const char *name;
|
||||||
|
size_t name_sz;
|
||||||
|
struct cpio_header hdr;
|
||||||
|
} files[CPIO_MAX_FILES];
|
||||||
|
};
|
||||||
|
|
||||||
|
static char hex(u8 c)
|
||||||
|
{
|
||||||
|
if (c <= 9)
|
||||||
|
return '0' + c;
|
||||||
|
return 'a' + c - 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_hex32(char *p, u32 val)
|
||||||
|
{
|
||||||
|
for (unsigned int i = 0; i < 8; ++i) {
|
||||||
|
u32 shift = 28 - (4 * i);
|
||||||
|
p[i] = hex((val >> shift) & 0xf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct cpio *cpio_init(void)
|
||||||
|
{
|
||||||
|
struct cpio *c = malloc(sizeof(*c));
|
||||||
|
if (!c)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
c->n_files = 0;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cpio_add(struct cpio *c, const char *name, u64 mode, const u8 *bfr, size_t sz)
|
||||||
|
{
|
||||||
|
struct cpio_header *hdr;
|
||||||
|
|
||||||
|
if (c->n_files >= CPIO_MAX_FILES) {
|
||||||
|
printf("cpio: cannot add more than %d files.\n", CPIO_MAX_FILES);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
c->files[c->n_files].ptr = bfr;
|
||||||
|
c->files[c->n_files].sz = sz;
|
||||||
|
c->files[c->n_files].name = name;
|
||||||
|
c->files[c->n_files].name_sz = strlen(name) + 1;
|
||||||
|
|
||||||
|
hdr = &c->files[c->n_files].hdr;
|
||||||
|
memcpy(hdr->magic, CPIO_HEADER_MAGIC, 6);
|
||||||
|
write_hex32(hdr->mode, mode);
|
||||||
|
write_hex32(hdr->nlink, 1);
|
||||||
|
write_hex32(hdr->filesize, sz);
|
||||||
|
write_hex32(hdr->namesize, strlen(name) + 1);
|
||||||
|
|
||||||
|
c->n_files++;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cpio_add_file(struct cpio *c, const char *name, const u8 *bfr, size_t sz)
|
||||||
|
{
|
||||||
|
return cpio_add(c, name, CPIO_MODE_FILE, bfr, sz);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cpio_add_dir(struct cpio *c, const char *name)
|
||||||
|
{
|
||||||
|
return cpio_add(c, name, CPIO_MODE_DIR, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t cpio_get_size(struct cpio *c)
|
||||||
|
{
|
||||||
|
size_t sz = 0;
|
||||||
|
|
||||||
|
for (u32 i = 0; i < c->n_files; ++i) {
|
||||||
|
sz += sizeof(struct cpio_header);
|
||||||
|
sz += c->files[i].name_sz;
|
||||||
|
sz = ALIGN_UP(sz, 4);
|
||||||
|
sz += c->files[i].sz;
|
||||||
|
sz = ALIGN_UP(sz, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sz;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t cpio_finalize(struct cpio *c, u8 *bfr, size_t bfr_size)
|
||||||
|
{
|
||||||
|
size_t off = 0;
|
||||||
|
|
||||||
|
if (cpio_get_size(c) > bfr_size)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (u32 i = 0; i < c->n_files; ++i) {
|
||||||
|
memcpy(bfr + off, &c->files[i].hdr, sizeof(struct cpio_header));
|
||||||
|
off += sizeof(struct cpio_header);
|
||||||
|
|
||||||
|
memcpy(bfr + off, c->files[i].name, c->files[i].name_sz);
|
||||||
|
off += c->files[i].name_sz;
|
||||||
|
off = ALIGN_UP(off, 4);
|
||||||
|
|
||||||
|
memcpy(bfr + off, c->files[i].ptr, c->files[i].sz);
|
||||||
|
off += c->files[i].sz;
|
||||||
|
off = ALIGN_UP(off, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
return off;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cpio_free(struct cpio *c)
|
||||||
|
{
|
||||||
|
free(c);
|
||||||
|
}
|
18
src/cpio.h
Normal file
18
src/cpio.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/* SPDX-License-Identifier: MIT */
|
||||||
|
|
||||||
|
#ifndef CPIO_H
|
||||||
|
#define CPIO_H
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
struct cpio;
|
||||||
|
|
||||||
|
struct cpio *cpio_init(void);
|
||||||
|
int cpio_add_file(struct cpio *c, const char *name, const u8 *bfr, size_t sz);
|
||||||
|
int cpio_add_dir(struct cpio *c, const char *name);
|
||||||
|
size_t cpio_get_size(struct cpio *c);
|
||||||
|
size_t cpio_finalize(struct cpio *c, u8 *bfr, size_t bfr_size);
|
||||||
|
void cpio_free(struct cpio *c);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue