menios
menios copied to clipboard
Migrate /bin utilities from FAT32 to ext2 partition
Goal
Migrate all /bin utilities and executables from the FAT32 boot partition to the ext2 root partition, establishing a proper UNIX filesystem layout with full permission and ownership support.
Context
Currently, /bin utilities live on the FAT32 partition, which has limitations:
- No POSIX permissions (all files executable by everyone)
- No ownership (UID/GID) support
- No symbolic link support
- Limited metadata
With ext2 as the root filesystem (#228), we can migrate /bin to enjoy:
- Proper file permissions (755 for executables, 644 for scripts)
- File ownership (root-owned system binaries)
- Symbolic links for alternative names
- Better security and organization
Definition of Done
- Build system: Compile binaries and install to ext2 partition
-
Migration script: Move existing
/binfrom FAT32 to ext2 - Permissions: Set proper permissions on all binaries (755)
- Ownership: Set proper ownership (root:root typically)
- Symbolic links: Create common aliases (sh → mosh, etc.)
-
PATH: Update default PATH to use ext2
/bin - Verification: All utilities work from new location
Current /bin Contents
Shell and Core Utilities
/bin/mosh # Default shell
/bin/init # Init process
/bin/sh → mosh # Shell symlink (future)
File Utilities
/bin/cat # Concatenate files
/bin/echo # Print text
/bin/ls # List directory
/bin/env # Environment variables
Process Management
/bin/ps # Process list
/bin/kill # Send signals
/bin/true # Return success
/bin/false # Return failure
Future Utilities
/bin/cp # Copy files
/bin/mv # Move files
/bin/rm # Remove files
/bin/mkdir # Make directory
/bin/rmdir # Remove directory
/bin/ln # Create links
/bin/chmod # Change permissions
/bin/chown # Change ownership
Implementation Details
Build System Changes
# Makefile changes for ext2 installation
# Build binaries
USERLAND_BINS = mosh init cat echo ls env ps kill true false
USERLAND_DIR = src/usermode
BIN_INSTALL_DIR = /tmp/menios_root/bin
# Compile each binary
$(USERLAND_BINS): %: $(USERLAND_DIR)/%.c
$(CC) $(CFLAGS) -o build/bin/$@ $< $(LDFLAGS)
# Install to ext2 partition
install-binaries: $(USERLAND_BINS)
@mkdir -p $(BIN_INSTALL_DIR)
@for bin in $(USERLAND_BINS); do \
cp build/bin/$$bin $(BIN_INSTALL_DIR)/$$bin; \
chmod 755 $(BIN_INSTALL_DIR)/$$bin; \
done
@echo "Installed $(words $(USERLAND_BINS)) binaries to ext2"
# Create symbolic links
install-symlinks:
@ln -sf mosh $(BIN_INSTALL_DIR)/sh
@ln -sf env $(BIN_INSTALL_DIR)/printenv
@echo "Created symbolic links"
# Full installation
install: install-binaries install-symlinks
Disk Image Build Process
#!/bin/bash
# build_system.sh - Updated for ext2 /bin
set -e
# 1. Build all binaries
make -C src/usermode all
# 2. Create disk image with partitions
./scripts/create_boot_disk.sh
# 3. Mount ext2 partition
LOOP=$(sudo losetup -fP --show menios.img)
mkdir -p /tmp/menios_root
sudo mount ${LOOP}p2 /tmp/menios_root
# 4. Create directory structure
sudo mkdir -p /tmp/menios_root/{bin,dev,tmp,proc,etc,home,usr,var,root,boot}
# 5. Install binaries with correct permissions
for binary in build/bin/*; do
sudo cp "$binary" /tmp/menios_root/bin/
sudo chmod 755 "/tmp/menios_root/bin/$(basename $binary)"
sudo chown root:root "/tmp/menios_root/bin/$(basename $binary)"
done
# 6. Create symbolic links
sudo ln -sf mosh /tmp/menios_root/bin/sh
# 7. Create initial /etc structure
sudo mkdir -p /tmp/menios_root/etc
echo "PATH=/bin:/usr/bin" | sudo tee /tmp/menios_root/etc/environment
echo "root:x:0:0:root:/root:/bin/sh" | sudo tee /tmp/menios_root/etc/passwd
# 8. Unmount and cleanup
sudo umount /tmp/menios_root
sudo losetup -d $LOOP
rm -rf /tmp/menios_root
echo "ext2 root partition populated successfully"
Runtime Migration (First Boot)
// Run once on first boot to migrate from FAT32 to ext2
int migrate_bin_to_ext2(void) {
struct stat st;
// Check if /bin already exists on ext2
if (stat("/bin/mosh", &st) == 0) {
kprintf("Migration: /bin already exists on ext2, skipping\n");
return 0;
}
kprintf("Migration: Copying /bin from FAT32 to ext2...\n");
// Create /bin directory on ext2
if (mkdir("/bin", 0755) < 0) {
kprintf("Migration: Failed to create /bin\n");
return -1;
}
// Mount FAT32 temporarily to /boot (if not already mounted)
// Copy each binary from /boot/bin/* to /bin/*
const char *binaries[] = {
"mosh", "init", "cat", "echo", "ls",
"env", "ps", "kill", "true", "false", NULL
};
for (int i = 0; binaries[i]; i++) {
char src[256], dst[256];
snprintf(src, sizeof(src), "/boot/bin/%s", binaries[i]);
snprintf(dst, sizeof(dst), "/bin/%s", binaries[i]);
if (copy_file(src, dst) < 0) {
kprintf("Migration: Warning - failed to copy %s\n", binaries[i]);
continue;
}
chmod(dst, 0755);
kprintf("Migration: Copied %s\n", binaries[i]);
}
// Create symbolic links
symlink("mosh", "/bin/sh");
kprintf("Migration: Completed successfully\n");
return 0;
}
Permission Setup
// Set proper permissions on binaries
struct binary_perms {
const char *path;
mode_t mode;
uid_t uid;
gid_t gid;
};
struct binary_perms bin_permissions[] = {
// Regular executables (owner rwx, group rx, other rx)
{ "/bin/mosh", 0755, 0, 0 },
{ "/bin/cat", 0755, 0, 0 },
{ "/bin/echo", 0755, 0, 0 },
{ "/bin/ls", 0755, 0, 0 },
{ "/bin/env", 0755, 0, 0 },
// System utilities (may want restricted)
{ "/bin/ps", 0755, 0, 0 },
{ "/bin/kill", 0755, 0, 0 },
// Init (critical system binary)
{ "/bin/init", 0750, 0, 0 }, // root only
{ NULL, 0, 0, 0 }
};
int setup_bin_permissions(void) {
for (int i = 0; bin_permissions[i].path; i++) {
struct binary_perms *bp = &bin_permissions[i];
if (chmod(bp->path, bp->mode) < 0) {
kprintf("Failed to set permissions on %s\n", bp->path);
return -1;
}
if (chown(bp->path, bp->uid, bp->gid) < 0) {
kprintf("Failed to set ownership on %s\n", bp->path);
return -1;
}
}
return 0;
}
Symbolic Link Creation
# Common shell aliases
ln -s /bin/mosh /bin/sh
# Alternative utility names
ln -s /bin/env /bin/printenv
# Future compatibility
ln -s /bin/true /bin/:
ln -s /bin/false /bin/false
Directory Structure After Migration
/ (ext2 root)
├── bin/
│ ├── cat (755, root:root)
│ ├── echo (755, root:root)
│ ├── env (755, root:root)
│ ├── false (755, root:root)
│ ├── init (750, root:root)
│ ├── kill (755, root:root)
│ ├── ls (755, root:root)
│ ├── mosh (755, root:root)
│ ├── ps (755, root:root)
│ ├── sh → mosh (symbolic link)
│ └── true (755, root:root)
│
├── boot/ (mount point for FAT32 sda1)
│ ├── kernel.elf
│ └── limine.cfg
│
├── etc/
│ ├── passwd
│ ├── group
│ └── environment
│
└── [other directories...]
Testing Strategy
- Build system test: Verify binaries installed to ext2
- Permission test: Verify all permissions set correctly
- Execution test: Run each binary from ext2 location
- Symbolic link test: Verify symlinks work
- PATH test: Ensure shell finds binaries
- Migration test: Test first-boot migration
- Fallback test: Verify FAT32 fallback still works
Environment Variables
# /etc/environment - Default environment
PATH=/bin:/usr/bin:/sbin:/usr/sbin
HOME=/root
SHELL=/bin/sh
TERM=linux
Init Process Updates
// init process should set proper PATH
void init_environment(void) {
// Read /etc/environment if exists
FILE *fp = fopen("/etc/environment", "r");
if (fp) {
char line[256];
while (fgets(line, sizeof(line), fp)) {
// Parse VAR=value and set environment
char *eq = strchr(line, '=');
if (eq) {
*eq = '\0';
setenv(line, eq + 1, 1);
}
}
fclose(fp);
} else {
// Fallback defaults
setenv("PATH", "/bin:/usr/bin", 1);
setenv("HOME", "/root", 1);
setenv("SHELL", "/bin/sh", 1);
}
}
Migration Checklist
- [ ] Update Makefile to install to ext2
- [ ] Create disk build script with ext2 /bin
- [ ] Implement permission setting
- [ ] Create symbolic links
- [ ] Update PATH in default environment
- [ ] Test all binaries from new location
- [ ] Document new directory layout
- [ ] Remove old FAT32 /bin references
Dependencies
- ext2 support: #227 (ext2 filesystem)
- Dual partition mount: #228 (FAT32 /boot + ext2 /)
- chmod/chown syscalls: Permission management syscalls
- symlink syscall: Symbolic link creation
Benefits
- Proper UNIX permissions on system binaries
- File ownership and security
- Symbolic link support for aliases
- Cleaner separation of boot and system files
- Foundation for multi-user system
- Better organized filesystem
Rollback Plan
- Keep FAT32 /bin as backup during transition
- Fallback PATH includes /boot/bin
- Can boot with old FAT32-only layout if needed
Files to Create/Modify
- Makefile - Binary installation updates
- scripts/build_system.sh - Disk creation script
- src/usermode/init.c - Environment setup
- etc/environment - Default environment file
- docs/FILESYSTEM_LAYOUT.md - Documentation
Deliverables
- Binaries installed to ext2 /bin
- Proper permissions (755) on all executables
- Symbolic links for common aliases
- Updated PATH to use ext2
- Migration script for first boot
- Documentation
Related Issues
- #228 - Dual partition mount (FAT32 /boot + ext2 /)
- #227 - ext2 filesystem support
- chmod/chown syscalls implementation (future)
Dependencies
Required (Blocking)
- #227 - Full ext2 implementation (need write support to create /bin on ext2)
- #228 - Dual partition mount (need ext2 mounted as /)
- chmod/chown syscalls - Need permission management (new issue needed)
- symlink syscall - Need symbolic link creation (new issue needed)
Part Of
- #227 - ext2 implementation (this is the migration/deployment phase)
Priority
Low - Nice organizational improvement, not blocking functionality
Justification
- Cosmetic/organizational improvement
- Binaries work fine from FAT32
- POSIX permissions nice but not critical yet
- Should wait until ext2 write support is stable
- No urgency until multi-user support needed
Implementation Phases
Phase 1: Build System (2-3 days)
- Update Makefile to install binaries to ext2
- Create disk image build script
- Partition formatting and file copying
Phase 2: Permission Setup (1-2 days)
- Implement chmod/chown in build scripts
- Set proper permissions (755 for executables)
- Set ownership (root:root)
Phase 3: Symbolic Links (1 day)
- Create /bin/sh → mosh symlink
- Create other common aliases
- Test link resolution
Phase 4: Environment (1-2 days)
- Create /etc/environment
- Update init to set PATH
- Default shell configuration
Phase 5: Testing (2-3 days)
- Verify all binaries work from ext2
- Test permissions
- Test symbolic links
- Migration script testing
Total Estimated: 1.5-2 weeks
Current Status
Blocked - Waiting for:
- #227 (ext2 write support) - Not started
- #228 (dual partition mount) - Blocked
- chmod/chown syscalls - Not created
- symlink syscall - Partially exists, needs testing
Recommend deferring this until #227 and #228 are complete and stable.
Testing Strategy
- Build system test: Verify binaries installed to ext2
- Permission test: Verify all permissions set correctly
- Execution test: Run each binary from ext2 location
- Symbolic link test: Verify symlinks work
- PATH test: Ensure shell finds binaries
- Migration test: Test first-boot migration
- Fallback test: Verify FAT32 fallback still works