mirror of
https://github.com/AsahiLinux/m1n1
synced 2024-11-24 23:53:04 +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 \
|
||||
bootlogo_128.o bootlogo_256.o \
|
||||
chickens.o \
|
||||
cpio.o \
|
||||
dart.o \
|
||||
exception.o exception_asm.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