Skip to content

Commit 5b4b6dd

Browse files
aero.py: speed up prepare_iso!
cold cached build: real 0m59.722s user 1m36.639s sys 0m12.023s Most of the time is spent in the `prepare_iso` function copying and creating the initramfs. This can be improved by copying the userland binaries into sysroot instead of copying the sysroot and userland binaries into one `build/initramfs_root` since that copy is expensive. After the improvement, cold cached build: real 0m28.471s user 1m28.544s sys 0m6.706s Signed-off-by: Andy-Python-Programmer <andypythonappdeveloper@gmail.com>
1 parent 9cbea2f commit 5b4b6dd

File tree

5 files changed

+49
-50
lines changed

5 files changed

+49
-50
lines changed

aero.py

+18-40
Original file line numberDiff line numberDiff line change
@@ -422,19 +422,22 @@ def prepare_iso(args, kernel_bin, user_bins):
422422
shutil.copy(os.path.join(limine_path, 'limine-cd.bin'), iso_root)
423423
shutil.copy(os.path.join(limine_path, 'limine-cd-efi.bin'), iso_root)
424424

425-
initramfs_root = os.path.join(BUILD_DIR, 'initramfs_root')
426-
initramfs_bin = os.path.join(initramfs_root, 'usr', 'bin')
425+
sysroot_dir = os.path.join(SYSROOT_DIR, 'system-root')
426+
shutil.copytree(BASE_FILES_DIR, sysroot_dir, dirs_exist_ok=True)
427427

428-
if os.path.exists(initramfs_root):
429-
shutil.rmtree(initramfs_root)
428+
# dynamic linker (ld.so)
429+
mlibc = os.path.join(get_userland_package(), "mlibc")
430+
# gcc libraries required for rust programs
431+
gcc = os.path.join(get_userland_package(), "gcc")
430432

431-
sysroot_dir = os.path.join(SYSROOT_DIR, 'system-root')
433+
# FIXME
434+
if "host-rust-prebuilt" in str(mlibc):
435+
shutil.copytree(mlibc, sysroot_dir, dirs_exist_ok=True)
436+
shutil.copytree(gcc, sysroot_dir, dirs_exist_ok=True)
432437

433-
if os.path.exists(sysroot_dir):
434-
# copying the sysroot will auto-magically create the bin directory.
435-
shutil.copytree(sysroot_dir, initramfs_root)
436-
else:
437-
os.makedirs(initramfs_bin)
438+
for file in user_bins:
439+
bin_name = os.path.basename(file)
440+
shutil.copy(file, os.path.join(sysroot_dir, "usr", "bin", bin_name))
438441

439442
def find(path) -> List[str]:
440443
_, find_output, _ = run_command(['find', '.', '-type', 'f'],
@@ -447,40 +450,15 @@ def find(path) -> List[str]:
447450
lambda x: remove_prefix(x, './'), files_without_dot)
448451
files = list(files_without_prefix)
449452

450-
return files
451-
452-
def cp(src, dest):
453-
files = find(src)
454-
455-
for line in files:
456-
file = os.path.join(src, line)
457-
dest_file = os.path.join(dest, line)
458-
459-
os.makedirs(os.path.dirname(dest_file), exist_ok=True)
460-
shutil.copy(file, dest_file)
461-
462-
# dynamic linker (ld.so)
463-
mlibc = os.path.join(get_userland_package(), "mlibc")
464-
# gcc libraries required for rust programs
465-
gcc = os.path.join(get_userland_package(), "gcc")
466-
467-
if "host-rust-prebuilt" in str(mlibc):
468-
cp(mlibc, initramfs_root)
469-
cp(gcc, initramfs_root)
470-
471-
cp(BASE_FILES_DIR, initramfs_root)
472-
473-
for file in user_bins:
474-
bin_name = os.path.basename(file)
475-
476-
shutil.copy(file, os.path.join(initramfs_bin, bin_name))
453+
files.append("usr/lib/libiconv.so.2")
454+
return files
477455

478-
files = find(initramfs_root)
456+
files = find(sysroot_dir)
479457

480458
with open(os.path.join(iso_root, 'initramfs.cpio'), 'wb') as initramfs:
481459
cpio_input = '\n'.join(files)
482460
code, _, _ = run_command(['cpio', '-o', '-v'],
483-
cwd=initramfs_root,
461+
cwd=sysroot_dir,
484462
stdout=initramfs,
485463
stderr=subprocess.PIPE,
486464
input=cpio_input.encode('utf-8'))
@@ -529,7 +507,7 @@ def run_in_emulator(args, iso_path):
529507

530508
qemu_args = ['-cdrom', iso_path,
531509
'-M', 'q35',
532-
'-m', '9G',
510+
'-m', '9800M',
533511
'-smp', '5',
534512
'-serial', 'stdio']
535513

src/Cargo.lock

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Cargo.toml

-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,2 @@
11
[workspace]
22
members = ["aero_kernel", "aero_syscall", "aero_proc"]
3-
4-
[profile.release]
5-
debug = true

src/aero_kernel/Cargo.toml

+1-3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ intrusive-collections = "0.9.2"
3636
serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
3737
lai = { git = "https://github.com/aero-os/lai-rs" }
3838
uapi = { path = "../uapi" }
39+
cpio_reader = { git = "https://github.com/Andy-Python-Programmer/cpio_reader" }
3940

4041
[dependencies.vte]
4142
git = "https://github.com/Andy-Python-Programmer/vte"
@@ -51,8 +52,5 @@ path = "../aero_proc"
5152
[dependencies.aero_syscall]
5253
path = "../aero_syscall"
5354

54-
[dependencies.cpio_reader]
55-
git = "https://github.com/czapek1337/cpio_reader"
56-
5755
[build-dependencies]
5856
nasm-rs = { version = "0.2", features = ["parallel"] }

src/aero_kernel/src/fs/initramfs.rs

+28-2
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@
1818
*/
1919

2020
use alloc::sync::Arc;
21+
use cpio_reader::Mode;
2122

2223
use crate::fs::{FileSystemError, Path};
2324
use crate::mem::paging::PhysAddr;
2425

2526
use super::cache::DirCacheItem;
2627
use super::ramfs::RamFs;
2728

28-
use super::{root_dir, FileSystem, Result, MOUNT_MANAGER};
29+
use super::{root_dir, FileSystem, LookupMode, Result, MOUNT_MANAGER};
2930

3031
lazy_static::lazy_static! {
3132
static ref INIT_FILESYSTEM: Arc<InitRamFs> = InitRamFs::new();
@@ -56,8 +57,24 @@ pub(super) fn init() -> Result<()> {
5657
core::slice::from_raw_parts(base.as_ptr(), length as usize)
5758
};
5859

60+
let mut symlinks = alloc::vec![];
61+
5962
for entry in cpio_reader::iter_files(initrd) {
6063
let path = Path::new(entry.name());
64+
65+
if entry.mode().contains(Mode::SYMBOLIK_LINK) {
66+
// CPIO symbolically linked file's contain the target path as their contents.
67+
let target =
68+
core::str::from_utf8(entry.file()).map_err(|_| FileSystemError::InvalidPath)?;
69+
70+
let (parent, _) = path.parent_and_basename();
71+
72+
// We need to create symbolically linked files at the end, after all the
73+
// other files.
74+
symlinks.push((alloc::format!("{}/{}", parent.as_str(), target), path));
75+
continue;
76+
}
77+
6178
let component_count = path.components().count();
6279

6380
let mut cwd = root_dir().clone();
@@ -78,7 +95,16 @@ pub(super) fn init() -> Result<()> {
7895
}
7996
}
8097

81-
MOUNT_MANAGER.mount(root_dir().clone(), INIT_FILESYSTEM.clone())?;
98+
for (src, target) in symlinks {
99+
let src = super::lookup_path_with(root_dir().clone(), Path::new(&src), LookupMode::None)
100+
.expect(&alloc::format!("your mom {:?}", src));
101+
let (target_dir, target_name) = target.parent_and_basename();
82102

103+
let target = super::lookup_path_with(root_dir().clone(), target_dir, LookupMode::None)
104+
.expect(&alloc::format!("your dad {:?}", target));
105+
target.inode().link(target_name, src.inode()).unwrap();
106+
}
107+
108+
MOUNT_MANAGER.mount(root_dir().clone(), INIT_FILESYSTEM.clone())?;
83109
Ok(())
84110
}

0 commit comments

Comments
 (0)