Skip to content

Commit 822f7d2

Browse files
block: load root filesystem from disk
* load root filesystem from the disk * update mkimage to copy all the hidden files aswell * remove initramfs code in the kernel * keep track of the unused items in the cache so we can reuse them to avoid more memory allocations and disk i/o where applicable Signed-off-by: Andy-Python-Programmer <andypythonappdeveloper@gmail.com>
1 parent a6951d9 commit 822f7d2

File tree

17 files changed

+340
-322
lines changed

17 files changed

+340
-322
lines changed

aero.py

Lines changed: 4 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import subprocess
2626
import sys
2727
import tarfile
28+
import time
2829

2930
from typing import List
3031

@@ -76,9 +77,6 @@ def log_error(msg):
7677
7778
MODULE_PATH=boot:///term_background.bmp
7879
MODULE_CMDLINE=background
79-
80-
MODULE_PATH=boot:///initramfs.cpio
81-
MODULE_CMDLINE=initramfs
8280
"""
8381

8482

@@ -437,47 +435,6 @@ def prepare_iso(args, kernel_bin, user_bins):
437435
shutil.copy(os.path.join(limine_path, 'BOOTAA64.EFI'), efi_boot)
438436
shutil.copy(os.path.join(limine_path, 'BOOTX64.EFI'), efi_boot)
439437

440-
sysroot_dir = os.path.join(SYSROOT_DIR, 'system-root')
441-
shutil.copytree(BASE_FILES_DIR, sysroot_dir, dirs_exist_ok=True)
442-
443-
# dynamic linker (ld.so)
444-
mlibc = os.path.join(get_userland_package(), "mlibc")
445-
# gcc libraries required for rust programs
446-
gcc = os.path.join(get_userland_package(), "gcc")
447-
448-
# FIXME
449-
if "host-rust-prebuilt" in str(mlibc):
450-
shutil.copytree(mlibc, sysroot_dir, dirs_exist_ok=True)
451-
shutil.copytree(gcc, sysroot_dir, dirs_exist_ok=True)
452-
453-
for file in user_bins:
454-
bin_name = os.path.basename(file)
455-
shutil.copy(file, os.path.join(sysroot_dir, "usr", "bin", bin_name))
456-
457-
def find(path) -> List[str]:
458-
_, find_output, _ = run_command(['find', '.', '-type', 'f'],
459-
cwd=path,
460-
stdout=subprocess.PIPE)
461-
462-
files_without_dot = filter(
463-
lambda x: x != '.', find_output.decode('utf-8').splitlines())
464-
files_without_prefix = map(
465-
lambda x: remove_prefix(x, './'), files_without_dot)
466-
files = list(files_without_prefix)
467-
468-
files.append("usr/lib/libiconv.so.2")
469-
return files
470-
471-
files = find(sysroot_dir)
472-
473-
with open(os.path.join(iso_root, 'initramfs.cpio'), 'wb') as initramfs:
474-
cpio_input = '\n'.join(files)
475-
code, _, _ = run_command(['cpio', '-o', '-v'],
476-
cwd=sysroot_dir,
477-
stdout=initramfs,
478-
stderr=subprocess.PIPE,
479-
input=cpio_input.encode('utf-8'))
480-
481438
with open(os.path.join(iso_root, 'limine.cfg'), 'w') as limine_cfg:
482439
limine_cfg.write(LIMINE_TEMPLATE)
483440

@@ -641,6 +598,7 @@ def is_kvm_supported() -> bool:
641598

642599

643600
def main():
601+
t0 = time.time()
644602
args = parse_args()
645603

646604
# arch-aero_os
@@ -699,6 +657,8 @@ def main():
699657
kernel_bin = kernel_bin[0]
700658
iso_path = prepare_iso(args, kernel_bin, user_bins)
701659

660+
t1 = time.time()
661+
log_info(f"build completed in {t1 - t0:.2f} seconds")
702662
if not args.no_run:
703663
run_in_emulator(build_info, iso_path)
704664

src/Cargo.lock

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/aero_kernel/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,10 @@ lai = { git = "https://github.com/aero-os/lai-rs" }
4040
uapi = { path = "../uapi" }
4141
cpio_reader = { git = "https://github.com/Andy-Python-Programmer/cpio_reader" }
4242
static_assertions = "1.1.0"
43+
lru = "0.8.0"
44+
bytemuck = "1.12.1"
4345

4446
limine = { git = "https://github.com/limine-bootloader/limine-rs" }
45-
4647
cfg-if = "1.0"
4748

4849
# X86_64 specific dependencies:

src/aero_kernel/src/arch/x86_64/mod.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -194,13 +194,6 @@ extern "C" fn arch_aero_main() -> ! {
194194

195195
syscall::init();
196196

197-
crate::INITRD_MODULE.call_once(|| {
198-
modules
199-
.iter()
200-
.find(|e| e.cmdline.to_str().unwrap().to_str().unwrap() == "initramfs")
201-
.unwrap()
202-
});
203-
204197
let boot_time = BOOT_TIME.get_response().get().unwrap();
205198
time::EPOCH.store(boot_time.boot_time as _, Ordering::SeqCst);
206199

src/aero_kernel/src/drivers/block/nvme/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ impl<'a> Namespace<'a> {
262262
read_cmd.data_ptr.prp1 = buffer.addr().as_u64();
263263
}
264264

265-
self.controller.io_queue.lock().submit_command(read_cmd);
265+
self.controller.io_queue.lock_irq().submit_command(read_cmd);
266266

267267
// SAFETY: The buffer is initialized above.
268268
let buffer = unsafe { buffer.assume_init() };

src/aero_kernel/src/fs/block/gpt.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
* along with Aero. If not, see <https://www.gnu.org/licenses/>.
1818
*/
1919

20+
use crate::fs::block::BlockDeviceInterface;
21+
2022
use super::BlockDevice;
2123
use core::mem::MaybeUninit;
2224

@@ -126,7 +128,6 @@ impl Gpt {
126128
let mut header = Box::<GptTableHeader>::new_uninit();
127129

128130
controller
129-
.device()
130131
.read_block(1, header.as_bytes_mut())
131132
.expect("gpt: failed to read first sector");
132133

@@ -143,7 +144,6 @@ impl Gpt {
143144
let mut entry_list = Box::<[GptEntry]>::new_uninit_slice(header.num_entries as usize);
144145

145146
controller
146-
.device()
147147
.read_block(
148148
header.starting_lba as _,
149149
MaybeUninit::slice_as_bytes_mut(&mut entry_list),

src/aero_kernel/src/fs/block/mod.rs

Lines changed: 95 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,48 @@ use alloc::sync::{Arc, Weak};
2929
use alloc::vec::Vec;
3030

3131
use crate::fs::devfs::install_device;
32-
use crate::fs::{Path, Result, MOUNT_MANAGER};
32+
use crate::fs::{FileSystem, Result};
3333

3434
use crate::fs::ext2::Ext2;
3535
use crate::utils::sync::Mutex;
3636

37+
use super::cache::{Cache, Cacheable};
3738
use super::devfs::{alloc_device_marker, Device};
3839
use super::inode::INodeInterface;
3940

41+
type CachedBlockKey = (usize, usize); // (block device pointer, block)
42+
43+
struct CachedBlock {
44+
device: Weak<dyn CachedAccess>,
45+
block: usize,
46+
buffer: Box<[u8]>,
47+
}
48+
49+
impl CachedBlock {
50+
fn make_key(device: Weak<dyn CachedAccess>, block: usize) -> CachedBlockKey {
51+
(device.as_ptr() as *const u8 as usize, block)
52+
}
53+
}
54+
55+
impl Cacheable<CachedBlockKey> for CachedBlock {
56+
fn cache_key(&self) -> CachedBlockKey {
57+
Self::make_key(self.device.clone(), self.block)
58+
}
59+
}
60+
61+
lazy_static::lazy_static! {
62+
static ref BLOCK_CACHE: Arc<Cache<CachedBlockKey, CachedBlock>> = Cache::new();
63+
}
64+
4065
pub trait BlockDeviceInterface: Send + Sync {
4166
fn block_size(&self) -> usize;
4267

4368
fn read_block(&self, sector: usize, dest: &mut [MaybeUninit<u8>]) -> Option<usize>;
4469
fn write_block(&self, sector: usize, buf: &[u8]) -> Option<usize>;
70+
}
71+
72+
pub trait CachedAccess: BlockDeviceInterface {
73+
fn sref(&self) -> Weak<dyn CachedAccess>;
4574

4675
fn read(&self, offset: usize, dest: &mut [MaybeUninit<u8>]) -> Option<usize> {
4776
let mut progress = 0;
@@ -57,10 +86,26 @@ pub trait BlockDeviceInterface: Send + Sync {
5786
chunk = block_size - loc;
5887
}
5988

60-
let mut buffer = Box::<[u8]>::new_uninit_slice(block_size);
61-
self.read_block(block, MaybeUninit::slice_as_bytes_mut(&mut buffer))?;
89+
let key = CachedBlock::make_key(self.sref(), block);
90+
91+
if let Some(cached) = BLOCK_CACHE.get(key) {
92+
MaybeUninit::write_slice(
93+
&mut dest[progress..(progress + chunk)],
94+
&cached.buffer[loc..loc + chunk],
95+
);
96+
} else {
97+
let mut buffer = Box::<[u8]>::new_uninit_slice(block_size);
98+
99+
self.read_block(block, MaybeUninit::slice_as_bytes_mut(&mut buffer))?;
100+
dest[progress..(progress + chunk)].copy_from_slice(&buffer[loc..loc + chunk]);
101+
102+
BLOCK_CACHE.make_item_cached(CachedBlock {
103+
device: self.sref(),
104+
block,
105+
buffer: unsafe { buffer.assume_init() },
106+
});
107+
}
62108

63-
dest[progress..(progress + chunk)].copy_from_slice(&buffer[loc..loc + chunk]);
64109
progress += chunk;
65110
}
66111

@@ -85,25 +130,41 @@ pub struct BlockDevice {
85130
id: usize,
86131
name: String,
87132
dev: Arc<dyn BlockDeviceInterface>,
88-
self_ref: Weak<BlockDevice>,
133+
sref: Weak<BlockDevice>,
89134
}
90135

91136
impl BlockDevice {
92137
pub fn new(name: String, imp: Arc<dyn BlockDeviceInterface>) -> Arc<BlockDevice> {
93-
Arc::new_cyclic(|me| BlockDevice {
138+
Arc::new_cyclic(|sref| BlockDevice {
94139
id: alloc_device_marker(),
95140
name,
96141
dev: imp,
97-
self_ref: me.clone(),
142+
sref: sref.clone(),
98143
})
99144
}
100145

101146
pub fn name(&self) -> String {
102147
self.name.clone()
103148
}
149+
}
104150

105-
pub fn device(&self) -> Arc<dyn BlockDeviceInterface> {
106-
self.dev.clone()
151+
impl BlockDeviceInterface for BlockDevice {
152+
fn block_size(&self) -> usize {
153+
self.dev.block_size()
154+
}
155+
156+
fn read_block(&self, sector: usize, dest: &mut [MaybeUninit<u8>]) -> Option<usize> {
157+
self.dev.read_block(sector, dest)
158+
}
159+
160+
fn write_block(&self, sector: usize, buf: &[u8]) -> Option<usize> {
161+
self.dev.write_block(sector, buf)
162+
}
163+
}
164+
165+
impl CachedAccess for BlockDevice {
166+
fn sref(&self) -> Weak<dyn CachedAccess> {
167+
self.sref.clone()
107168
}
108169
}
109170

@@ -119,23 +180,27 @@ impl Device for BlockDevice {
119180
}
120181

121182
fn inode(&self) -> Arc<dyn INodeInterface> {
122-
self.self_ref.upgrade().unwrap().clone()
183+
self.sref.upgrade().unwrap().clone()
123184
}
124185
}
125186

126187
struct PartitionBlockDevice {
188+
sref: Weak<Self>,
189+
127190
offset: usize, // offset in sectors
128191
size: usize, // capacity in sectors
129192
device: Arc<dyn BlockDeviceInterface>,
130193
}
131194

132195
impl PartitionBlockDevice {
133-
fn new(offset: usize, size: usize, device: Arc<dyn BlockDeviceInterface>) -> Self {
134-
Self {
196+
fn new(offset: usize, size: usize, device: Arc<dyn BlockDeviceInterface>) -> Arc<Self> {
197+
Arc::new_cyclic(|sref| Self {
198+
sref: sref.clone(),
199+
135200
offset,
136201
size,
137202
device,
138-
}
203+
})
139204
}
140205
}
141206

@@ -161,6 +226,12 @@ impl BlockDeviceInterface for PartitionBlockDevice {
161226
}
162227
}
163228

229+
impl CachedAccess for PartitionBlockDevice {
230+
fn sref(&self) -> Weak<dyn CachedAccess> {
231+
self.sref.clone()
232+
}
233+
}
234+
164235
pub fn launch() -> Result<()> {
165236
let mut blocks_copy = Vec::<Arc<BlockDevice>>::new();
166237

@@ -189,19 +260,27 @@ pub fn launch() -> Result<()> {
189260
);
190261

191262
let name = alloc::format!("{}p{}", block.name(), i);
192-
let partition_device = PartitionBlockDevice::new(start, size, block.device());
193-
let device = BlockDevice::new(name, Arc::new(partition_device));
263+
let partition_device = PartitionBlockDevice::new(start, size, block.clone());
264+
let device = BlockDevice::new(name, partition_device);
194265

195266
install_block_device(device.clone())?;
196267

197268
// Check what filesystem is on this partition and mount it.
198269
if let Some(ext2) = Ext2::new(device.clone()) {
199270
log::info!("gpt: found ext2 filesystem on {}!", device.name());
200-
MOUNT_MANAGER.mount(super::lookup_path(Path::new("/mnt"))?, ext2)?;
271+
272+
super::ROOT_FS.call_once(|| ext2.clone());
273+
super::ROOT_DIR.call_once(|| ext2.root_dir().clone());
201274
}
202275
}
203276
}
204277
}
205278

279+
super::devfs::init()?;
280+
log::info!("installed devfs");
281+
282+
super::procfs::init()?;
283+
log::info!("installed procfs");
284+
206285
Ok(())
207286
}

0 commit comments

Comments
 (0)