mirror of
https://gitlab.com/bztsrc/bootboot.git
synced 2023-02-13 20:54:32 -05:00
Added ext2 generation to mkbootimg
This commit is contained in:
parent
9315889381
commit
c1bc19f1f5
9 changed files with 430 additions and 9 deletions
|
@ -5,7 +5,7 @@ Előre lefordított binárisok mellékelve, egyből használhatók.
|
|||
|
||||
1. *x86_64-efi* a preferált indítási mód x86_64-en.
|
||||
Szabvány GNU eszköztár plusz néhány fájl a gnuefi-ből (mellékelve).
|
||||
[bootboot.efi](https://gitlab.com/bztsrc/bootboot/raw/master/dist/bootboot.efi) (100k), [bootboot.rom](https://gitlab.com/bztsrc/bootboot/raw/master/dist/bootboot.rom) (100k)
|
||||
[bootboot.efi](https://gitlab.com/bztsrc/bootboot/raw/master/dist/bootboot.efi) (101k), [bootboot.rom](https://gitlab.com/bztsrc/bootboot/raw/master/dist/bootboot.rom) (101k)
|
||||
|
||||
2. *x86_64-bios* BIOS, Multiboot (GRUB), El Torito (CDROM), bővítő ROM és Linux boot kompatíbilis, RÉGI betöltő.
|
||||
Ha újra akarod fordítani, szükséged lesz a fasm-ra (nincs mellékelve).
|
||||
|
|
|
@ -5,7 +5,7 @@ I provide pre-compiled images ready for use.
|
|||
|
||||
1. *x86_64-efi* the preferred way of booting on x86_64 architecture.
|
||||
Standard GNU toolchain and a few files from gnuefi (included).
|
||||
[bootboot.efi](https://gitlab.com/bztsrc/bootboot/raw/master/dist/bootboot.efi) (100k), [bootboot.rom](https://gitlab.com/bztsrc/bootboot/raw/master/dist/bootboot.rom) (100k)
|
||||
[bootboot.efi](https://gitlab.com/bztsrc/bootboot/raw/master/dist/bootboot.efi) (101k), [bootboot.rom](https://gitlab.com/bztsrc/bootboot/raw/master/dist/bootboot.rom) (101k)
|
||||
|
||||
2. *x86_64-bios* BIOS, Multiboot (GRUB), El Torito (CDROM), Expansion ROM and Linux boot compatible, OBSOLETE loader.
|
||||
If you want to recompile this, you'll need fasm (not included).
|
||||
|
|
|
@ -7,8 +7,8 @@ Ez egy minden az egyben, többplatformos, függőség nélküli lemezkép kreál
|
|||
forgatva). Egy lemezkonfigurációt kell megadni neki JSON-ben, és létrehozza az ESP FAT boot partíciót a szükséges betöltő
|
||||
fájlokkal, GPT táblával, PMBR-el, stb. Továbbá képes létrehozni az induló memórialemezképet egy könyvtár tartalmából (jelenleg
|
||||
`cpio`, `tar`, `jamesm` (James Molloy initrdje), `echfs` és az `FS/Z` támogatott, de a kód úgy lett megírva, hogy könnyű legyen
|
||||
bővíteni). Szemben ezzel, könyvtárból generálható partíció `fat` (hosszú fájlnevekkel), `minix` (Minix V3, POSIX
|
||||
jogosultságokkal és eszközfájlokkal), `tar`, `echfs`, `FS/Z` fájlrendszerekhez.
|
||||
bővíteni). Szemben ezzel, könyvtárból generálható partíció `fat` (hosszú fájlnevekkel), `minix` (Minix V3), `ext2` (Rev 1),
|
||||
`tar`, `echfs` és `FS/Z` fájlrendszerekhez.
|
||||
|
||||
A kigenerált képet leellenőriztem fdisk-el, valamint a gdisk verify funkciójával. A FAT partíció tesztelve lett fsck.vfat-al
|
||||
és UEFI förmverrel, továbbá Raspberry Pi-n. Az ISO9660-es rész iat-vel (ISO9660 Analyzer Tool) és Linux mounttal lett tesztelve.
|
||||
|
|
|
@ -7,8 +7,7 @@ This is an all-in-one, multiplatform, dependency-free disk image creator tool. Y
|
|||
flexible JSON, and it generates ESP FAT boot partition with the required loader files, GPT partitioning table, PMBR, etc. It
|
||||
also creates an initrd from a directory (currently `cpio`, `tar`, `jamesm` (James Molloy's initrd), `echfs` and `FS/Z`
|
||||
supported, but the code is written in a way that it is easily expandable). In contrast, partitions can be generated from
|
||||
directories for `fat` (with long file names), `minix` (Minix V3 with POSIX permissions and device files), `tar`, `echfs`,
|
||||
`FS/Z` filesystems.
|
||||
directories for `fat` (with long file names), `minix` (Minix V3), `ext2` (Rev 1), `tar`, `echfs` and `FS/Z` file systems.
|
||||
|
||||
The generated image was tested with fdisk, and with the verify function of gdisk. The FAT partition was tested with fsck.vfat
|
||||
and with TianoCore UEFI firmware and on Raspberry Pi. The ISO9660 part tested with iat (ISO9660 Analyzer Tool) and Linux mount.
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -5,7 +5,7 @@ extern unsigned char binary_boot_bin[512];
|
|||
#define sizeof_bootboot_bin 13312
|
||||
extern unsigned char binary_bootboot_bin[9285];
|
||||
#define sizeof_bootboot_efi 103614
|
||||
extern unsigned char binary_bootboot_efi[46258];
|
||||
extern unsigned char binary_bootboot_efi[46278];
|
||||
#define sizeof_bootboot_img 35488
|
||||
extern unsigned char binary_bootboot_img[20151];
|
||||
#define sizeof_bootboot_rv64 8192
|
||||
|
|
409
mkbootimg/ext2.c
Normal file
409
mkbootimg/ext2.c
Normal file
|
@ -0,0 +1,409 @@
|
|||
/*
|
||||
* mkbootimg/ext2.c
|
||||
*
|
||||
* Copyright (C) 2017 - 2021 bzt (bztsrc@gitlab)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use, copy,
|
||||
* modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* This file is part of the BOOTBOOT Protocol package.
|
||||
* @brief very simple ext2 file system driver
|
||||
*
|
||||
*/
|
||||
#include "main.h"
|
||||
|
||||
#define EXT2_SUPER_MAGIC 0xEF53
|
||||
#define EXT2_S_IFLNK 0xA000
|
||||
#define EXT2_S_IFREG 0x8000
|
||||
#define EXT2_S_IFBLK 0x6000
|
||||
#define EXT2_S_IFDIR 0x4000
|
||||
#define EXT2_S_IFCHR 0x2000
|
||||
#define EXT2_S_IFIFO 0x1000
|
||||
|
||||
enum {
|
||||
EXT2_FT_UNKNOWN,
|
||||
EXT2_FT_REG_FILE,
|
||||
EXT2_FT_DIR,
|
||||
EXT2_FT_CHRDEV,
|
||||
EXT2_FT_BLKDEV,
|
||||
EXT2_FT_FIFO,
|
||||
EXT2_FT_SOCK,
|
||||
EXT2_FT_SYMLINK
|
||||
};
|
||||
|
||||
#define SECSIZE 4096
|
||||
|
||||
typedef struct {
|
||||
uint32_t bg_block_bitmap;
|
||||
uint32_t bg_inode_bitmap;
|
||||
uint32_t bg_inode_table;
|
||||
uint16_t bg_free_blocks_count;
|
||||
uint16_t bg_free_inodes_count;
|
||||
uint16_t bg_used_dirs_count;
|
||||
uint16_t bg_flags;
|
||||
uint8_t pad[12];
|
||||
} __attribute__((packed)) ext_bg_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t loader[1024];
|
||||
uint32_t s_inodes_count;
|
||||
uint32_t s_blocks_count;
|
||||
uint32_t s_r_blocks_count;
|
||||
uint32_t s_free_blocks_count;
|
||||
uint32_t s_free_inodes_count;
|
||||
uint32_t s_first_data_block;
|
||||
uint32_t s_log_block_size;
|
||||
uint32_t s_log_frag_size;
|
||||
uint32_t s_blocks_per_group;
|
||||
uint32_t s_frags_per_group;
|
||||
uint32_t s_inodes_per_group;
|
||||
uint32_t s_mtime;
|
||||
uint32_t s_wtime;
|
||||
uint16_t s_mnt_count;
|
||||
uint16_t s_max_mnt_count;
|
||||
uint16_t s_magic;
|
||||
uint16_t s_state;
|
||||
uint16_t s_errors;
|
||||
uint16_t s_minor_rev_level;
|
||||
uint32_t s_lastcheck;
|
||||
uint32_t s_checkinterval;
|
||||
uint32_t s_creator_os;
|
||||
uint32_t s_rev_level;
|
||||
uint16_t s_def_resuid;
|
||||
uint16_t s_def_resgid;
|
||||
uint32_t s_first_ino;
|
||||
uint16_t s_inode_size;
|
||||
uint16_t s_block_group_nr;
|
||||
uint32_t s_feature_compat;
|
||||
uint32_t s_feature_incompat;
|
||||
uint32_t s_feature_ro_compat;
|
||||
uint8_t s_uuid[16];
|
||||
uint8_t pad1[SECSIZE-120-1024];
|
||||
ext_bg_t s_bg[SECSIZE/sizeof(ext_bg_t)];
|
||||
} __attribute__((packed)) ext_sb_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t i_mode;
|
||||
uint16_t i_uid;
|
||||
uint32_t i_size;
|
||||
uint32_t i_atime;
|
||||
uint32_t i_ctime;
|
||||
uint32_t i_mtime;
|
||||
uint32_t i_dtime;
|
||||
uint16_t i_gid;
|
||||
uint16_t i_links_count;
|
||||
uint32_t i_blocks;
|
||||
uint32_t i_flags;
|
||||
uint32_t i_osd1;
|
||||
uint32_t i_block[15];
|
||||
uint32_t i_generation;
|
||||
uint32_t i_file_acl;
|
||||
uint32_t i_dir_acl;
|
||||
uint32_t i_faddr;
|
||||
uint16_t i_osd2[6];
|
||||
} __attribute__((packed)) ext_inode_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t inode;
|
||||
uint16_t rec_len;
|
||||
uint8_t name_len;
|
||||
uint8_t type;
|
||||
} __attribute__((packed)) ext_dirent_t;
|
||||
|
||||
uint32_t ext_numblk, ext_numbg, ext_nextinode, ext_nextblk, ext_blkgap, ext_root;
|
||||
uint8_t *ext_lastdir;
|
||||
ext_sb_t *ext_sb;
|
||||
|
||||
int ext_alloc_blk()
|
||||
{
|
||||
int r, g = ext_nextblk / ext_sb->s_blocks_per_group, o = ext_nextblk % ext_sb->s_blocks_per_group;
|
||||
if(ext_nextblk + 1 >= ext_sb->s_blocks_count || ext_sb->s_free_blocks_count < 1) {
|
||||
fprintf(stderr,"mkbootimg: partition #%d %s\r\n", fs_no, lang[ERR_TOOBIG]);
|
||||
exit(1);
|
||||
}
|
||||
fs_base[ext_sb->s_bg[g].bg_block_bitmap * SECSIZE + o/8] |= 1<<(o&7);
|
||||
ext_sb->s_bg[g].bg_free_blocks_count--;
|
||||
ext_sb->s_free_blocks_count--;
|
||||
r = ext_nextblk++;
|
||||
if(!(ext_nextblk % ext_sb->s_blocks_per_group)) ext_nextblk += ext_blkgap;
|
||||
return r;
|
||||
}
|
||||
|
||||
int ext_alloc_inode(uint16_t mode, uint32_t size, uint16_t uid, uint16_t gid, time_t t)
|
||||
{
|
||||
ext_inode_t *inode;
|
||||
int g = ext_nextinode / ext_sb->s_inodes_per_group, o = ext_nextinode % ext_sb->s_inodes_per_group;
|
||||
if(ext_nextinode + 1 >= ext_sb->s_inodes_count || ext_sb->s_free_inodes_count < 1) {
|
||||
fprintf(stderr,"mkbootimg: partition #%d %s\r\n", fs_no, lang[ERR_TOOMANY]);
|
||||
exit(1);
|
||||
}
|
||||
fs_base[ext_sb->s_bg[g].bg_inode_bitmap * SECSIZE + o/8] |= 1<<(o&7);
|
||||
inode = (ext_inode_t*)(fs_base + ext_sb->s_bg[g].bg_inode_table * SECSIZE);
|
||||
inode[o].i_mode = mode | (!(mode & 0xFFF) ? 0755 : 0);
|
||||
inode[o].i_size = size;
|
||||
inode[o].i_blocks = (size + 511) / 512;
|
||||
inode[o].i_uid = uid;
|
||||
inode[o].i_gid = gid;
|
||||
inode[o].i_ctime = inode[o].i_atime = inode[o].i_mtime = (uint32_t)t;
|
||||
if((mode & 0xF000) == EXT2_S_IFDIR)
|
||||
ext_sb->s_bg[g].bg_used_dirs_count++;
|
||||
ext_sb->s_bg[g].bg_free_inodes_count--;
|
||||
ext_sb->s_free_inodes_count--;
|
||||
ext_nextinode++;
|
||||
return ext_nextinode;
|
||||
}
|
||||
|
||||
void ext_add_to_inode(uint32_t ino, uint32_t blk, char *name)
|
||||
{
|
||||
int i, j;
|
||||
ext_inode_t *inode;
|
||||
uint32_t *ind, *dind;
|
||||
int g = (ino - 1) / ext_sb->s_inodes_per_group, o = (ino - 1) % ext_sb->s_inodes_per_group;
|
||||
inode = (ext_inode_t*)(fs_base + ext_sb->s_bg[g].bg_inode_table * SECSIZE);
|
||||
for(i = 0; i < 12; i++)
|
||||
if(!inode[o].i_block[i]) {
|
||||
inode[o].i_block[i] = blk;
|
||||
return;
|
||||
}
|
||||
if(!inode[o].i_block[12])
|
||||
inode[o].i_block[12] = ext_alloc_blk();
|
||||
ind = (uint32_t*)(fs_base + inode[o].i_block[12] * SECSIZE);
|
||||
for(i = 0; i < SECSIZE / 4; i++)
|
||||
if(!ind[i]) {
|
||||
ind[i] = blk;
|
||||
return;
|
||||
}
|
||||
if(!inode[o].i_block[13])
|
||||
inode[o].i_block[13] = ext_alloc_blk();
|
||||
dind = (uint32_t*)(fs_base + inode[o].i_block[13] * SECSIZE);
|
||||
for(j = 0; j < SECSIZE / 4; j++) {
|
||||
if(!dind[j])
|
||||
dind[j] = ext_alloc_blk();
|
||||
ind = (uint32_t*)(fs_base + dind[j] * SECSIZE);
|
||||
for(i = 0; i < SECSIZE / 4; i++)
|
||||
if(!ind[i]) {
|
||||
ind[i] = blk;
|
||||
return;
|
||||
}
|
||||
}
|
||||
fprintf(stderr,"mkbootimg: partition #%d %s: %s\r\n", fs_no, lang[ERR_TOOBIG], name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uint8_t *ext_add_dirent(uint8_t *dir, uint32_t toinode, uint32_t ino, uint8_t type, char *name, int len)
|
||||
{
|
||||
ext_dirent_t *de;
|
||||
ext_inode_t *inode;
|
||||
int k;
|
||||
int g = (ino - 1) / ext_sb->s_inodes_per_group, o = (ino - 1) % ext_sb->s_inodes_per_group;
|
||||
if(ino) {
|
||||
inode = (ext_inode_t*)(fs_base + ext_sb->s_bg[g].bg_inode_table * SECSIZE);
|
||||
inode[o].i_links_count++;
|
||||
}
|
||||
if(ext_lastdir && dir) {
|
||||
if((uint32_t)(dir - fs_base)/SECSIZE != (uint32_t)(dir - fs_base + len + 8)/SECSIZE) {
|
||||
dir = NULL;
|
||||
} else
|
||||
((ext_dirent_t*)ext_lastdir)->rec_len = dir - ext_lastdir;
|
||||
}
|
||||
if(!dir) {
|
||||
k = ext_alloc_blk();
|
||||
ext_add_to_inode(toinode, k, name);
|
||||
dir = fs_base + k * SECSIZE;
|
||||
}
|
||||
de = (ext_dirent_t*)dir;
|
||||
de->inode = ino;
|
||||
de->rec_len = SECSIZE - ((uintptr_t)(dir - fs_base) & (SECSIZE - 1));
|
||||
de->name_len = len;
|
||||
de->type = type;
|
||||
if(name && len)
|
||||
memcpy(dir + 8, name, len);
|
||||
ext_lastdir = dir;
|
||||
return dir + ((len + 3) & ~3) + 8;
|
||||
}
|
||||
|
||||
void ext_open(gpt_t *gpt_entry)
|
||||
{
|
||||
uint32_t i, j, k, l, n, m, o;
|
||||
if(!gpt_entry) { fprintf(stderr,"mkbootimg: %s ext2.\r\n", lang[ERR_BADINITRDTYPE]); exit(1); }
|
||||
ext_numblk = (gpt_entry->last - gpt_entry->start + 1) * 512 / SECSIZE;
|
||||
if(ext_numblk < 8) { fprintf(stderr,"mkbootimg: partition #%d %s\r\n", fs_no, lang[ERR_NOSIZE]); exit(1); }
|
||||
fs_len = ext_numblk * SECSIZE;
|
||||
fs_base = realloc(fs_base, fs_len);
|
||||
if(!fs_base) { fprintf(stderr,"mkbootimg: %s\r\n",lang[ERR_MEM]); exit(1); }
|
||||
memset(fs_base, 0, fs_len);
|
||||
ext_nextinode = ext_nextblk = 0;
|
||||
ext_numbg = ext_numblk / (SECSIZE<<3);
|
||||
if(ext_numbg < 1) ext_numbg = 1;
|
||||
if(ext_numbg > (int)(SECSIZE/sizeof(ext_bg_t)) - 1) {
|
||||
fprintf(stderr,"mkbootimg: partition #%d %s\r\n", fs_no, lang[ERR_TOOMANY]);
|
||||
exit(1);
|
||||
}
|
||||
ext_sb = (ext_sb_t*)fs_base;
|
||||
ext_sb->s_blocks_count = ext_numblk;
|
||||
ext_sb->s_r_blocks_count = ext_numblk * 5 / 100;
|
||||
ext_sb->s_log_block_size = ext_sb->s_log_frag_size = 2;
|
||||
ext_sb->s_blocks_per_group = ext_sb->s_frags_per_group = (SECSIZE<<3);
|
||||
ext_sb->s_inodes_count = ext_sb->s_blocks_count;
|
||||
ext_sb->s_inodes_per_group = ext_sb->s_inodes_count / ext_numbg;
|
||||
if(ext_sb->s_inodes_per_group > (SECSIZE<<3)) ext_sb->s_inodes_per_group = (SECSIZE<<3);
|
||||
ext_sb->s_inodes_count = ext_sb->s_inodes_per_group * ext_numbg;
|
||||
if(ext_sb->s_inodes_count > ext_sb->s_blocks_count)
|
||||
ext_sb->s_inodes_count = ext_sb->s_blocks_count;
|
||||
ext_sb->s_free_inodes_count = ext_sb->s_inodes_count;
|
||||
ext_sb->s_wtime = ext_sb->s_lastcheck = (uint32_t)t;
|
||||
ext_sb->s_max_mnt_count = 65535;
|
||||
ext_sb->s_magic = EXT2_SUPER_MAGIC;
|
||||
ext_sb->s_state = ext_sb->s_errors = 1;
|
||||
ext_sb->s_rev_level = 1;
|
||||
ext_sb->s_feature_incompat = 2;
|
||||
ext_sb->s_first_ino = 11;
|
||||
ext_sb->s_inode_size = 128;
|
||||
memcpy(fs_base + 1024 + 104, &gpt_entry->guid, 16);
|
||||
for(i = k = m = 0; i < ext_numbg; i++) {
|
||||
j = ((ext_sb->s_blocks_per_group+7)/8 + SECSIZE - 1) / SECSIZE;
|
||||
if(k + j > ext_numblk) j = ext_numblk - k;
|
||||
ext_sb->s_bg[i].bg_block_bitmap = (SECSIZE<<3) * i + 2;
|
||||
ext_sb->s_bg[i].bg_inode_bitmap = (SECSIZE<<3) * i + 2 + j;
|
||||
ext_sb->s_bg[i].bg_inode_table = (SECSIZE<<3) * i + 3 + j;
|
||||
o = m + ext_sb->s_inodes_per_group > ext_sb->s_inodes_count ? ext_sb->s_inodes_count - m : ext_sb->s_inodes_per_group;
|
||||
if((uint32_t)o > ext_sb->s_free_inodes_count) o = ext_sb->s_free_inodes_count;
|
||||
l = 3 + j + (o * sizeof(ext_inode_t) + SECSIZE - 1) / SECSIZE;
|
||||
for(n = 0; n < l; n++)
|
||||
fs_base[((SECSIZE<<3) * i + 2) * SECSIZE + n/8] |= 1<<(n&7);
|
||||
if(!ext_nextblk) ext_nextblk = ext_blkgap = l;
|
||||
ext_sb->s_bg[i].bg_free_inodes_count = o;
|
||||
ext_sb->s_bg[i].bg_free_blocks_count = (ext_numblk - k > (SECSIZE<<3) ? (SECSIZE<<3) : ext_numblk - k) - l;
|
||||
ext_sb->s_free_blocks_count += ext_sb->s_bg[i].bg_free_blocks_count;
|
||||
k += ext_sb->s_blocks_per_group;
|
||||
m += ext_sb->s_inodes_per_group;
|
||||
}
|
||||
ext_alloc_inode(EXT2_S_IFREG, 0, 0, 0, t); /* 1. bad blocks list inode */
|
||||
ext_root = ext_alloc_inode(EXT2_S_IFDIR, SECSIZE, 0, 0, t); /* 2. root directory inode */
|
||||
ext_alloc_inode(EXT2_S_IFREG, 0, 0, 0, t); /* 3. acl index inode */
|
||||
ext_alloc_inode(EXT2_S_IFREG, 0, 0, 0, t); /* 4. acl data inode */
|
||||
ext_alloc_inode(EXT2_S_IFREG, 0, 0, 0, t); /* 5. loader inode */
|
||||
ext_alloc_inode(EXT2_S_IFREG, 0, 0, 0, t); /* 6. undelete inode */
|
||||
ext_alloc_inode(EXT2_S_IFREG, 0, 0, 0, t); /* 7. resize inode */
|
||||
ext_alloc_inode(EXT2_S_IFREG, 0, 0, 0, t); /* 8. journal inode */
|
||||
ext_alloc_inode(EXT2_S_IFREG, 0, 0, 0, t); /* 9. exclude inode */
|
||||
ext_alloc_inode(EXT2_S_IFREG, 0, 0, 0, t); /* 10. replica inode */
|
||||
i = ext_alloc_inode(EXT2_S_IFDIR|0700, 4*SECSIZE, 0, 0, t); /* 11. lost+found inode, needs 4 blocks at minimum */
|
||||
ext_add_dirent(ext_add_dirent(ext_add_dirent(
|
||||
NULL, ext_root, ext_root, EXT2_FT_DIR, ".", 1),
|
||||
ext_root, ext_root, EXT2_FT_DIR, "..", 2),
|
||||
ext_root, i, EXT2_FT_DIR, "lost+found", 10);
|
||||
ext_add_dirent(ext_add_dirent(NULL, i, i, EXT2_FT_DIR, ".", 1), i, ext_root, EXT2_FT_DIR, "..", 2);
|
||||
ext_add_dirent(NULL, i, 0, EXT2_FT_UNKNOWN, NULL, 0);
|
||||
ext_add_dirent(NULL, i, 0, EXT2_FT_UNKNOWN, NULL, 0);
|
||||
ext_add_dirent(NULL, i, 0, EXT2_FT_UNKNOWN, NULL, 0);
|
||||
}
|
||||
|
||||
void ext_add(struct stat *st, char *name, unsigned char *content, int size)
|
||||
{
|
||||
uint8_t *dir_entry, *blk, t = EXT2_FT_REG_FILE;
|
||||
ext_inode_t *inode;
|
||||
uint32_t n, parent = ext_root;
|
||||
int i, k, g, o;
|
||||
char *end, *fn = strrchr(name, '/');
|
||||
if(!fn) fn = name; else fn++;
|
||||
if(!strcmp(fn, ".") || !strcmp(fn, "..")) return;
|
||||
if(!S_ISREG(st->st_mode) && !S_ISDIR(st->st_mode) && !S_ISLNK(st->st_mode) && !S_ISCHR(st->st_mode) && !S_ISBLK(st->st_mode))
|
||||
return;
|
||||
if(S_ISDIR(st->st_mode)) t = EXT2_FT_DIR; else
|
||||
if(S_ISLNK(st->st_mode)) t = EXT2_FT_SYMLINK; else
|
||||
if(S_ISCHR(st->st_mode)) t = EXT2_FT_CHRDEV; else
|
||||
if(S_ISBLK(st->st_mode)) t = EXT2_FT_BLKDEV;
|
||||
n = ext_alloc_inode(st->st_mode, st->st_size, st->st_uid, st->st_gid, st->st_mtime);
|
||||
/* Enter name in directory */
|
||||
fn = name;
|
||||
end = strchr(name, '/');
|
||||
if(!end) end = name + strlen(name);
|
||||
i = k = 0; ext_lastdir = NULL;
|
||||
again:
|
||||
/* FIXME: this doesn't handle indirect and double indirect data */
|
||||
g = (parent - 1) / ext_sb->s_inodes_per_group; o = (parent - 1) % ext_sb->s_inodes_per_group;
|
||||
inode = (ext_inode_t*)(fs_base + ext_sb->s_bg[g].bg_inode_table * SECSIZE);
|
||||
if(k > 11) {
|
||||
fprintf(stderr,"mkbootimg: partition #%d %s: %s\r\n", fs_no, lang[ERR_TOOMANY], name);
|
||||
exit(1);
|
||||
}
|
||||
if(!inode[o].i_block[k])
|
||||
dir_entry = ext_lastdir = NULL;
|
||||
else {
|
||||
dir_entry = blk = (uint8_t*)(fs_base + inode[o].i_block[k] * SECSIZE);
|
||||
while(((ext_dirent_t*)dir_entry)->inode) {
|
||||
if(((ext_dirent_t*)dir_entry)->name_len == end - fn && !memcmp(dir_entry + 8, fn, end - fn)) {
|
||||
parent = ((ext_dirent_t*)dir_entry)->inode; i = k = 0; ext_lastdir = NULL;
|
||||
fn = end + 1;
|
||||
end = *end ? strchr(fn, '/') : NULL;
|
||||
if(!end) end = fn + strlen(fn);
|
||||
goto again;
|
||||
}
|
||||
ext_lastdir = dir_entry;
|
||||
if((uint32_t)i + ((ext_dirent_t*)dir_entry)->rec_len >= inode[o].i_size) {
|
||||
dir_entry += ((((ext_dirent_t*)dir_entry)->name_len + 3) & ~3) + 8;
|
||||
break;
|
||||
}
|
||||
i += ((ext_dirent_t*)dir_entry)->rec_len;
|
||||
dir_entry += ((ext_dirent_t*)dir_entry)->rec_len;
|
||||
if(dir_entry - blk >= SECSIZE) { k++; goto again; }
|
||||
}
|
||||
}
|
||||
ext_add_dirent(dir_entry, parent, n, t, fn, end - fn);
|
||||
|
||||
if(S_ISDIR(st->st_mode)) {
|
||||
ext_add_dirent(ext_add_dirent(NULL, n, n, EXT2_FT_DIR, ".", 1), n, parent, EXT2_FT_DIR, "..", 2);
|
||||
} else
|
||||
if(S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode)) {
|
||||
g = (n - 1) / ext_sb->s_inodes_per_group; o = (n - 1) % ext_sb->s_inodes_per_group;
|
||||
inode = (ext_inode_t*)(fs_base + ext_sb->s_bg[g].bg_inode_table * SECSIZE);
|
||||
inode[o].i_block[0] = st->st_rdev;
|
||||
} else
|
||||
if(S_ISLNK(st->st_mode)) {
|
||||
if(size >= SECSIZE) {
|
||||
fprintf(stderr,"mkbootimg: partition #%d %s: %s\r\n", fs_no, lang[ERR_TOOBIG], name);
|
||||
exit(1);
|
||||
}
|
||||
i = ext_alloc_blk();
|
||||
memcpy(fs_base + i * SECSIZE, content, k);
|
||||
ext_add_to_inode(n, i, name);
|
||||
} else {
|
||||
while(size) {
|
||||
k = size > SECSIZE ? SECSIZE : size;
|
||||
i = ext_alloc_blk();
|
||||
memcpy(fs_base + i * SECSIZE, content, k);
|
||||
ext_add_to_inode(n, i, name);
|
||||
content += SECSIZE;
|
||||
size -= k;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ext_close()
|
||||
{
|
||||
ext_sb_t *sb;
|
||||
uint32_t i;
|
||||
for(i = 1; i < ext_numbg && (int)i * (SECSIZE<<3) + 2 * SECSIZE <= fs_len; i++) {
|
||||
sb = (ext_sb_t*)(fs_base + i * (SECSIZE<<3));
|
||||
memcpy(sb, fs_base, 2 * SECSIZE);
|
||||
sb->s_block_group_nr = i;
|
||||
}
|
||||
}
|
|
@ -52,6 +52,10 @@ void fat_open(gpt_t *gpt_entry);
|
|||
void fat_add(struct stat *st, char *name, unsigned char *content, int size);
|
||||
void fat_close();
|
||||
|
||||
void ext_open(gpt_t *gpt_entry);
|
||||
void ext_add(struct stat *st, char *name, unsigned char *content, int size);
|
||||
void ext_close();
|
||||
|
||||
void jamesm_open(gpt_t *gpt_entry);
|
||||
void jamesm_add(struct stat *st, char *name, unsigned char *content, int size);
|
||||
void jamesm_close();
|
||||
|
@ -59,21 +63,25 @@ void jamesm_close();
|
|||
/*** specify file system drivers and GPT file system types here ***/
|
||||
/* for simplicity, first list the ones with drivers, and types only afterwards */
|
||||
fsdrv_t fsdrv[] = {
|
||||
/* not on partitions, initrd only */
|
||||
{ "jamesm", {0}, jamesm_open, jamesm_add, jamesm_close },
|
||||
{ "cpio", {0}, cpio_open, cpio_add, cpio_close },
|
||||
/* for both partitions and initrds */
|
||||
{ "tar", { 0x65706154, 0x4120, 0x6372, { 0x68,0x69,0x76,0x65,0x20,0x46,0x53,0x20} }, tar_open, tar_add, tar_close },
|
||||
{ "echfs", { 0x66686365, 0x6973, 0x7673, { 0x65,0x72,0x79,0x6C,0x61,0x6D,0x65,0x00} }, ech_open, ech_add, ech_close },
|
||||
{ "minix", { 0xB7AADF00, 0xDE27, 0x11CA, { 0xA5,0x74,0x56,0x72,0x69,0x6A,0x65,0x55} }, mnx_open, mnx_add, mnx_close },
|
||||
{ "fat", { 0xEBD0A0A2, 0xB9E5, 0x4433, { 0x87,0xC0,0x68,0xB6,0xB7,0x26,0x99,0xC7} }, fat_open, fat_add, fat_close },
|
||||
{ "ext2", { 0x0FC63DAF, 0x8483, 0x4772, { 0x8E,0x79,0x3D,0x69,0xD8,0x47,0x7D,0xE4} }, ext_open, ext_add, ext_close },
|
||||
{ "FS/Z", { 0x5A2F534F, 0x0000, 0x5346, { 0x2F,0x5A,0x00,0x00,0x00,0x00,0x00,0x00} }, fsz_open, fsz_add, fsz_close },
|
||||
/* partition type only, without drivers */
|
||||
{ "OS/Z usr (x86_64)", { 0x5A2F534F, 0x8664, 0x5346, { 0x2F,0x5A,0x00,0x00,0x75,0x73,0x72,0x00} }, NULL, NULL, NULL },
|
||||
{ "OS/Z usr (AArch64)", { 0x5A2F534F, 0xAA64, 0x5346, { 0x2F,0x5A,0x00,0x00,0x75,0x73,0x72,0x00} }, NULL, NULL, NULL },
|
||||
{ "OS/Z usr (RiscV64)", { 0x5A2F534F, 0x5064, 0x5346, { 0x2F,0x5A,0x00,0x00,0x75,0x73,0x72,0x00} }, NULL, NULL, NULL },
|
||||
{ "OS/Z var", { 0x5A2F534F, 0x0000, 0x5346, { 0x2F,0x5A,0x00,0x00,0x76,0x61,0x72,0x00} }, NULL, NULL, NULL },
|
||||
{ "OS/Z home", { 0x5A2F534F, 0x0000, 0x5346, { 0x2F,0x5A,0x00,0x00,0x68,0x6F,0x6D,0x65} }, NULL, NULL, NULL },
|
||||
{ "OS/Z swap", { 0x5A2F534F, 0x0000, 0x5346, { 0x2F,0x5A,0x00,0x00,0x73,0x77,0x61,0x70} }, NULL, NULL, NULL },
|
||||
{ "ZFS", { 0x6A898CC3, 0x1DD2, 0x11B2, { 0x99,0xA6,0x08,0x00,0x20,0x73,0x66,0x31} }, NULL, NULL, NULL },
|
||||
{ "ntfs", { 0xEBD0A0A2, 0xB9E5, 0x4433, { 0x87,0xC0,0x68,0xB6,0xB7,0x26,0x99,0xC7} }, NULL, NULL, NULL },
|
||||
{ "ext4", { 0x0FC63DAF, 0x8483, 0x4772, { 0x8E,0x79,0x3D,0x69,0xD8,0x47,0x7D,0xE4} }, NULL, NULL, NULL },
|
||||
{ "ufs", { 0x516E7CB6, 0x6ECF, 0x11D6, { 0x8F,0xF8,0x00,0x02,0x2D,0x09,0x71,0x2B} }, NULL, NULL, NULL },
|
||||
{ "p9", { 0xC91818F9, 0x8025, 0x47AF, { 0x89,0xD2,0xF0,0x30,0xD7,0x00,0x0C,0x2C} }, NULL, NULL, NULL },
|
||||
{ "Intel Fast Flash", { 0xD3BFE2DE, 0x3DAF, 0x11DF, { 0xBA,0x40,0xE3,0xA5,0x56,0xD8,0x95,0x93} }, NULL, NULL, NULL },
|
||||
|
|
|
@ -322,6 +322,11 @@ void mnx_add(struct stat *st, char *name, unsigned char *content, int size)
|
|||
do {
|
||||
/* FIXME: this doesn't handle indirect and double indirect data */
|
||||
ino = (inode_t*)(fs_base + mnx_inode_offset * DEFAULT_BLOCK_SIZE + (parent-1) * sizeof(inode_t));
|
||||
if(!ino->i_zone[k]) break;
|
||||
if(k >= NR_DZONES) {
|
||||
fprintf(stderr,"mkbootimg: partition #%d %s: %s\r\n", fs_no, lang[ERR_TOOBIG], name);
|
||||
exit(1);
|
||||
}
|
||||
dir_entry = (direct_t*)(fs_base + ino->i_zone[k] * DEFAULT_BLOCK_SIZE);
|
||||
if(!memcmp(dir_entry[i].d_name, fn, end - fn) && !dir_entry[i].d_name[end - fn]) {
|
||||
parent = dir_entry[i].d_ino; i = k = 0;
|
||||
|
|
Loading…
Reference in a new issue