2023-03-31 19:08:50 +01:00
|
|
|
/*
|
2023-04-03 19:13:42 +01:00
|
|
|
* SPDX-FileCopyrightText: Copyright (c) 2015 Grzegorz Kostka (kostka.grzegorz@gmail.com)
|
|
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
2023-03-31 19:08:50 +01:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
*
|
|
|
|
* - Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* - Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* - The name of the author may not be used to endorse or promote products
|
|
|
|
* derived from this software without specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
|
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
|
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
|
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*
|
|
|
|
* Modifications:
|
|
|
|
* SPDX-FileCopyrightText: 2023 Richard Masters <grick23@gmail.com>
|
|
|
|
* SPDX-License-Identifier: MIT
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
|
|
|
#include <ext4.h>
|
|
|
|
#include <ext4_mkfs.h>
|
|
|
|
#include "../blockdev/linux/file_dev.h"
|
|
|
|
#include "../blockdev/windows/file_windows.h"
|
|
|
|
|
|
|
|
#define BLOCK_SIZE 1024
|
|
|
|
#define FILENAME_LENGTH 256
|
2024-01-01 23:46:32 +00:00
|
|
|
#define INITRD_MB 1280
|
2023-03-31 19:08:50 +01:00
|
|
|
|
|
|
|
const char *input_name = NULL;
|
|
|
|
/**@brief Block device handle.*/
|
|
|
|
static struct ext4_blockdev *bd;
|
|
|
|
/**@brief Block cache handle.*/
|
|
|
|
static struct ext4_bcache *bc;
|
|
|
|
static struct ext4_fs fs;
|
|
|
|
|
|
|
|
|
|
|
|
static struct ext4_mkfs_info info = {
|
|
|
|
.block_size = BLOCK_SIZE,
|
|
|
|
.journal = false,
|
|
|
|
.inode_size = 128,
|
|
|
|
};
|
|
|
|
|
|
|
|
#define MKDEV(major, minor) (((major) << 8) | (minor))
|
|
|
|
|
|
|
|
static bool open_filedev(void)
|
|
|
|
{
|
|
|
|
file_dev_name_set(input_name);
|
|
|
|
bd = file_dev_get();
|
|
|
|
if (!bd) {
|
2023-05-20 16:20:01 +01:00
|
|
|
puts("open_filedev: fail");
|
2023-03-31 19:08:50 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool lwext4_mount(struct ext4_blockdev *bdev, struct ext4_bcache *bcache)
|
|
|
|
{
|
|
|
|
int r;
|
|
|
|
|
|
|
|
bc = bcache;
|
|
|
|
bd = bdev;
|
|
|
|
|
|
|
|
if (!bd) {
|
2023-05-20 16:20:01 +01:00
|
|
|
puts("lwext4_mount: no block device");
|
2023-03-31 19:08:50 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ext4_dmask_set(DEBUG_ALL); */
|
|
|
|
|
|
|
|
r = ext4_device_register(bd, "ext4_fs");
|
|
|
|
if (r != EOK) {
|
|
|
|
printf("ext4_device_register: rc = %d\n", r);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = ext4_mount("ext4_fs", "/mp/", false);
|
|
|
|
if (r != EOK) {
|
|
|
|
printf("ext4_mount: rc = %d\n", r);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = ext4_recover("/mp/");
|
|
|
|
if (r != EOK && r != ENOTSUP) {
|
|
|
|
printf("ext4_recover: rc = %d\n", r);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ext4_cache_write_back("/mp/", 1); */
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool lwext4_umount(void)
|
|
|
|
{
|
|
|
|
int r;
|
|
|
|
|
|
|
|
/* ext4_cache_write_back("/mp/", 0); */
|
|
|
|
|
|
|
|
r = ext4_umount("/mp/");
|
|
|
|
if (r != EOK) {
|
|
|
|
printf("ext4_umount: fail %d", r);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-04-03 19:13:42 +01:00
|
|
|
bool copy_file(char *src_path, char *dest_path)
|
|
|
|
{
|
2023-03-31 19:08:50 +01:00
|
|
|
|
2023-04-03 19:13:42 +01:00
|
|
|
printf("copy_file: %s\n", src_path);
|
2023-03-31 19:08:50 +01:00
|
|
|
ext4_file dest_file;
|
|
|
|
FILE *src_file = fopen(src_path, "rb");
|
|
|
|
if (!src_file) {
|
|
|
|
printf("fopen '%s' error.\n", src_path);
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
fseek(src_file, 0, SEEK_END);
|
|
|
|
int src_len = ftell(src_file);
|
|
|
|
char * src_mem = malloc(src_len);
|
|
|
|
int err;
|
|
|
|
|
|
|
|
fseek(src_file, 0, SEEK_SET);
|
|
|
|
if (src_len > 0) {
|
|
|
|
int read_len = fread(src_mem, src_len, 1, src_file);
|
|
|
|
fclose(src_file);
|
|
|
|
if (read_len < 1) {
|
|
|
|
printf("src fread error file: '%s' read count: %d\n", src_path, read_len);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
err = ext4_fopen(&dest_file, dest_path, "wb");
|
|
|
|
if (err != EOK) {
|
2023-05-20 16:20:01 +01:00
|
|
|
printf("ext4_open error: %d\n", err);
|
2023-03-31 19:08:50 +01:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (src_len > 0) {
|
|
|
|
err = ext4_fwrite(&dest_file, src_mem, src_len, 0);
|
|
|
|
if (err != EOK) {
|
2023-05-20 16:20:01 +01:00
|
|
|
printf("ext4_fwrite error: %d\n", err);
|
2023-03-31 19:08:50 +01:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
err = ext4_fclose(&dest_file);
|
|
|
|
if (err != EOK) {
|
2023-05-20 16:20:01 +01:00
|
|
|
printf("ext4_fclose error: %d\n", err);
|
2023-03-31 19:08:50 +01:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(src_mem);
|
|
|
|
}
|
|
|
|
|
2023-04-03 19:13:42 +01:00
|
|
|
bool copy_file_list(char *file_list_path)
|
|
|
|
{
|
2023-03-31 19:08:50 +01:00
|
|
|
char src_filename[FILENAME_LENGTH];
|
|
|
|
char dst_filename[FILENAME_LENGTH];
|
|
|
|
|
|
|
|
FILE *file_list = fopen(file_list_path, "r");
|
|
|
|
while(fgets(src_filename, FILENAME_LENGTH, file_list)) {
|
|
|
|
/* Skip comments */
|
|
|
|
if (src_filename[0] == '#') {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
src_filename[strlen(src_filename) - 1] = 0; /* strip newline */
|
|
|
|
strcpy(dst_filename, "/mp");
|
|
|
|
strcat(dst_filename, src_filename);
|
|
|
|
copy_file(src_filename, dst_filename);
|
|
|
|
}
|
|
|
|
fclose(file_list);
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
char zeros[BLOCK_SIZE];
|
|
|
|
|
|
|
|
unsigned int next_file_address;
|
2023-11-08 00:30:20 +00:00
|
|
|
|
2023-03-31 19:08:50 +01:00
|
|
|
next_file_address = *((unsigned int *) 0x7F8D);
|
|
|
|
|
2023-11-28 03:15:04 +00:00
|
|
|
printf("Starting fiwix.ext2 at addr 0x%08x\n", next_file_address);
|
2023-03-31 19:08:50 +01:00
|
|
|
|
|
|
|
/* Create zeroed out disk image file */
|
2023-11-28 03:15:04 +00:00
|
|
|
input_name = "/boot/fiwix.ext2";
|
2023-03-31 19:08:50 +01:00
|
|
|
|
|
|
|
memset(zeros, 0, BLOCK_SIZE);
|
|
|
|
FILE *ext2file = fopen(input_name, "w");
|
|
|
|
int b;
|
|
|
|
for (b=0; b < (BLOCK_SIZE * INITRD_MB); b++)
|
|
|
|
fwrite(zeros, BLOCK_SIZE, 1, ext2file);
|
|
|
|
fclose(ext2file);
|
|
|
|
|
|
|
|
if (!open_filedev()) {
|
|
|
|
printf("open_filedev error\n");
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ext4_dmask_set(DEBUG_ALL); */
|
|
|
|
|
|
|
|
err = ext4_mkfs(&fs, bd, &info, F_SET_EXT2_V0);
|
|
|
|
if (err != EOK) {
|
2023-05-20 16:20:01 +01:00
|
|
|
printf("ext4_mkfs error: %d\n", err);
|
2023-03-31 19:08:50 +01:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(&info, 0, sizeof(struct ext4_mkfs_info));
|
|
|
|
err = ext4_mkfs_read_info(bd, &info);
|
|
|
|
if (err != EOK) {
|
|
|
|
printf("ext4_mkfs_read_info error: %d\n", err);
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("Created filesystem with parameters:\n");
|
|
|
|
printf("Size: %"PRIu64"\n", info.len);
|
|
|
|
printf("Block size: %"PRIu32"\n", info.block_size);
|
|
|
|
printf("Blocks per group: %"PRIu32"\n", info.blocks_per_group);
|
|
|
|
printf("Inodes per group: %"PRIu32"\n", info.inodes_per_group);
|
|
|
|
printf("Inode size: %"PRIu32"\n", info.inode_size);
|
|
|
|
printf("Inodes: %"PRIu32"\n", info.inodes);
|
|
|
|
printf("Journal blocks: %"PRIu32"\n", info.journal_blocks);
|
|
|
|
printf("Features ro_compat: 0x%x\n", info.feat_ro_compat);
|
|
|
|
printf("Features compat: 0x%x\n", info.feat_compat);
|
|
|
|
printf("Features incompat: 0x%x\n", info.feat_incompat);
|
|
|
|
printf("BG desc reserve: %"PRIu32"\n", info.bg_desc_reserve_blocks);
|
|
|
|
printf("Descriptor size: %"PRIu32"\n",info.dsc_size);
|
|
|
|
printf("Label: %s\n", info.label);
|
|
|
|
|
|
|
|
if (!lwext4_mount(bd, bc))
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
2023-05-20 16:20:01 +01:00
|
|
|
puts("ext4_dir_mk /mp/dev");
|
2023-03-31 19:08:50 +01:00
|
|
|
err = ext4_dir_mk("/mp/dev");
|
|
|
|
if (err != EOK) {
|
2023-05-20 16:20:01 +01:00
|
|
|
printf("ext4_dir_mk error: %d\n", err);
|
2023-03-31 19:08:50 +01:00
|
|
|
}
|
Remove the notion of "sys*"
- This idea originates from very early in the project and was, at the
time, a very easy way to categorise things.
- Now, it doesn't really make much sense - it is fairly arbitary, often
occuring when there is a change in kernel, but not from builder-hex0
to fiwix, and sysb is in reality completely unnecessary.
- In short, the sys* stuff is a bit of a mess that makes the project
more difficult to understand.
- This puts everything down into one folder and has a manifest file that
is used to generate the build scripts on the fly rather than using
coded scripts.
- This is created in the "seed" stage.
stage0-posix -- (calls) --> seed -- (generates) --> main steps
Alongside this change there are a variety of other smaller fixups to the
general structure of the live-bootstrap rootfs.
- Creating a rootfs has become much simpler and is defined as code in
go.sh. The new structure, for an about-to-be booted system, is
/
-- /steps (direct copy of steps/)
-- /distfiles (direct copy of distfiles/)
-- all files from seed/*
-- all files from seed/stage0-posix/*
- There is no longer such a thing as /usr/include/musl, this didn't
really make any sense, as musl is the final libc used. Rather, to
separate musl and mes, we have /usr/include/mes, which is much easier
to work with.
- This also makes mes easier to blow away later.
- A few things that weren't properly in packages have been changed;
checksum-transcriber, simple-patch, kexec-fiwix have all been given
fully qualified package names.
- Highly breaking change, scripts now exist in their package directory
but NOT WITH THE packagename.sh. Rather, they use pass1.sh, pass2.sh,
etc. This avoids manual definition of passes.
- Ditto with patches; default directory is patches, but then any patch
series specific to a pass are named patches-passX.
2023-11-06 23:51:23 +00:00
|
|
|
puts("ext4_dir_mk /mp/tmp");
|
|
|
|
err = ext4_dir_mk("/mp/tmp");
|
|
|
|
if (err != EOK) {
|
|
|
|
printf("ext4_dir_mk error: %d\n", err);
|
|
|
|
}
|
2023-03-31 19:08:50 +01:00
|
|
|
|
2023-05-20 16:20:01 +01:00
|
|
|
puts("ext4_mknod /mp/dev/console");
|
2023-03-31 19:08:50 +01:00
|
|
|
err = ext4_mknod("/mp/dev/console", EXT4_DE_CHRDEV, MKDEV(5, 1));
|
|
|
|
if (err != EOK) {
|
2023-05-20 16:20:01 +01:00
|
|
|
printf("ext4_mknod error: %d\n", err);
|
2023-03-31 19:08:50 +01:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
2023-05-20 16:20:01 +01:00
|
|
|
puts("ext4_mknod /mp/dev/ram0");
|
2023-05-10 15:33:42 +01:00
|
|
|
err = ext4_mknod("/mp/dev/ram0", EXT4_DE_BLKDEV, MKDEV(1, 0));
|
|
|
|
if (err != EOK) {
|
2023-05-20 16:20:01 +01:00
|
|
|
printf("ext4_mknod error: %d\n", err);
|
2023-05-10 15:33:42 +01:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
2023-05-20 16:20:01 +01:00
|
|
|
puts("ext4_mknod /mp/dev/ram1");
|
2023-05-10 15:33:42 +01:00
|
|
|
err = ext4_mknod("/mp/dev/ram1", EXT4_DE_BLKDEV, MKDEV(1, 1));
|
|
|
|
if (err != EOK) {
|
2023-05-20 16:20:01 +01:00
|
|
|
printf("ext4_mknod error: %d\n", err);
|
2023-05-10 15:33:42 +01:00
|
|
|
return EXIT_FAILURE;
|
|
|
|
}
|
2023-03-31 19:08:50 +01:00
|
|
|
|
Remove the notion of "sys*"
- This idea originates from very early in the project and was, at the
time, a very easy way to categorise things.
- Now, it doesn't really make much sense - it is fairly arbitary, often
occuring when there is a change in kernel, but not from builder-hex0
to fiwix, and sysb is in reality completely unnecessary.
- In short, the sys* stuff is a bit of a mess that makes the project
more difficult to understand.
- This puts everything down into one folder and has a manifest file that
is used to generate the build scripts on the fly rather than using
coded scripts.
- This is created in the "seed" stage.
stage0-posix -- (calls) --> seed -- (generates) --> main steps
Alongside this change there are a variety of other smaller fixups to the
general structure of the live-bootstrap rootfs.
- Creating a rootfs has become much simpler and is defined as code in
go.sh. The new structure, for an about-to-be booted system, is
/
-- /steps (direct copy of steps/)
-- /distfiles (direct copy of distfiles/)
-- all files from seed/*
-- all files from seed/stage0-posix/*
- There is no longer such a thing as /usr/include/musl, this didn't
really make any sense, as musl is the final libc used. Rather, to
separate musl and mes, we have /usr/include/mes, which is much easier
to work with.
- This also makes mes easier to blow away later.
- A few things that weren't properly in packages have been changed;
checksum-transcriber, simple-patch, kexec-fiwix have all been given
fully qualified package names.
- Highly breaking change, scripts now exist in their package directory
but NOT WITH THE packagename.sh. Rather, they use pass1.sh, pass2.sh,
etc. This avoids manual definition of passes.
- Ditto with patches; default directory is patches, but then any patch
series specific to a pass are named patches-passX.
2023-11-06 23:51:23 +00:00
|
|
|
copy_file_list("/steps/lwext4-1.0.0-lb1/files/fiwix-file-list.txt");
|
2023-03-31 19:08:50 +01:00
|
|
|
|
|
|
|
if (!lwext4_umount())
|
|
|
|
return EXIT_FAILURE;
|
|
|
|
|
2023-05-20 16:20:01 +01:00
|
|
|
puts("Fiwix ext2 initrd created successfully.");
|
2023-03-31 19:08:50 +01:00
|
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|