Load init from initfs
This commit is contained in:
		
							parent
							
								
									00db6ddd62
								
							
						
					
					
						commit
						f2ca411cd6
					
				
					 3 changed files with 94 additions and 10 deletions
				
			
		|  | @ -133,11 +133,23 @@ pub extern fn kmain() { | |||
|     let pid = syscall::getpid(); | ||||
|     println!("BSP: {:?}", pid); | ||||
| 
 | ||||
|     assert_eq!(syscall::open("debug:".as_bytes(), 0), Ok(0)); | ||||
|     assert_eq!(syscall::open("debug:".as_bytes(), 0), Ok(1)); | ||||
|     assert_eq!(syscall::open("debug:".as_bytes(), 0), Ok(2)); | ||||
|     assert_eq!(syscall::open(b"debug:", 0), Ok(0)); | ||||
|     assert_eq!(syscall::open(b"debug:", 0), Ok(1)); | ||||
|     assert_eq!(syscall::open(b"debug:", 0), Ok(2)); | ||||
| 
 | ||||
|     let elf = elf::Elf::from(include_bytes!("../build/userspace/init")).expect("could not load elf"); | ||||
|     let init_file = syscall::open(b"initfs:init", 0).expect("failed to open initfs:init"); | ||||
|     let mut init_data = collections::Vec::new(); | ||||
|     loop { | ||||
|         let mut buf = [0; 65536]; | ||||
|         let count = syscall::read(init_file, &mut buf).expect("failed to read initfs:init"); | ||||
|         if count > 0 { | ||||
|             init_data.extend_from_slice(&buf[..count]); | ||||
|         } else { | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     let elf = elf::Elf::from(&init_data).expect("could not load elf"); | ||||
|     elf.run(); | ||||
| 
 | ||||
|     /* | ||||
|  | @ -163,12 +175,9 @@ pub extern fn kmain_ap(id: usize) { | |||
|     let pid = syscall::getpid(); | ||||
|     println!("AP {}: {:?}", id, pid); | ||||
| 
 | ||||
|     assert_eq!(syscall::open("debug:".as_bytes(), 0), Ok(0)); | ||||
|     assert_eq!(syscall::open("debug:".as_bytes(), 0), Ok(1)); | ||||
|     assert_eq!(syscall::open("debug:".as_bytes(), 0), Ok(2)); | ||||
| 
 | ||||
|     let elf = elf::Elf::from(include_bytes!("../build/userspace/init")).expect("could not load elf"); | ||||
|     elf.run(); | ||||
|     assert_eq!(syscall::open(b"debug:", 0), Ok(0)); | ||||
|     assert_eq!(syscall::open(b"debug:", 0), Ok(1)); | ||||
|     assert_eq!(syscall::open(b"debug:", 0), Ok(2)); | ||||
| 
 | ||||
|     loop { | ||||
|         unsafe { interrupt::enable_and_halt() } | ||||
|  |  | |||
							
								
								
									
										70
									
								
								kernel/scheme/initfs.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								kernel/scheme/initfs.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,70 @@ | |||
| use collections::BTreeMap; | ||||
| 
 | ||||
| use syscall::{Error, Result}; | ||||
| use super::Scheme; | ||||
| 
 | ||||
| struct Handle { | ||||
|     data: &'static [u8], | ||||
|     seek: usize | ||||
| } | ||||
| 
 | ||||
| pub struct InitFsScheme { | ||||
|     next_id: usize, | ||||
|     files: BTreeMap<&'static [u8], &'static [u8]>, | ||||
|     handles: BTreeMap<usize, Handle> | ||||
| } | ||||
| 
 | ||||
| impl InitFsScheme { | ||||
|     pub fn new() -> InitFsScheme { | ||||
|         let mut files: BTreeMap<&'static [u8], &'static [u8]> = BTreeMap::new(); | ||||
| 
 | ||||
|         files.insert(b"init", include_bytes!("../../build/userspace/init")); | ||||
| 
 | ||||
|         InitFsScheme { | ||||
|             next_id: 0, | ||||
|             files: files, | ||||
|             handles: BTreeMap::new() | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl Scheme for InitFsScheme { | ||||
|     fn open(&mut self, path: &[u8], _flags: usize) -> Result<usize> { | ||||
|         let data = self.files.get(path).ok_or(Error::NoEntry)?; | ||||
|         let id = self.next_id; | ||||
|         self.next_id += 1; | ||||
|         self.handles.insert(id, Handle { | ||||
|             data: data, | ||||
|             seek: 0 | ||||
|         }); | ||||
|         Ok(id) | ||||
|     } | ||||
| 
 | ||||
|     /// Read the file `number` into the `buffer`
 | ||||
|     ///
 | ||||
|     /// Returns the number of bytes read
 | ||||
|     fn read(&mut self, file: usize, buffer: &mut [u8]) -> Result<usize> { | ||||
|         let mut handle = self.handles.get_mut(&file).ok_or(Error::BadFile)?; | ||||
| 
 | ||||
|         let mut i = 0; | ||||
|         while i < buffer.len() && handle.seek < handle.data.len() { | ||||
|             buffer[i] = handle.data[handle.seek]; | ||||
|             i += 1; | ||||
|             handle.seek += 1; | ||||
|         } | ||||
| 
 | ||||
|         Ok(i) | ||||
|     } | ||||
| 
 | ||||
|     /// Write the `buffer` to the `file`
 | ||||
|     ///
 | ||||
|     /// Returns the number of bytes written
 | ||||
|     fn write(&mut self, _file: usize, _buffer: &[u8]) -> Result<usize> { | ||||
|         Err(Error::NotPermitted) | ||||
|     } | ||||
| 
 | ||||
|     /// Close the file `number`
 | ||||
|     fn close(&mut self, file: usize) -> Result<()> { | ||||
|         self.handles.remove(&file).ok_or(Error::BadFile).and(Ok(())) | ||||
|     } | ||||
| } | ||||
|  | @ -16,10 +16,14 @@ use spin::{Once, Mutex, RwLock, RwLockReadGuard, RwLockWriteGuard}; | |||
| use syscall::{Error, Result}; | ||||
| 
 | ||||
| use self::debug::DebugScheme; | ||||
| use self::initfs::InitFsScheme; | ||||
| 
 | ||||
| /// Debug scheme
 | ||||
| pub mod debug; | ||||
| 
 | ||||
| /// InitFS scheme
 | ||||
| pub mod initfs; | ||||
| 
 | ||||
| /// Limit on number of schemes
 | ||||
| pub const SCHEME_MAX_SCHEMES: usize = 65536; | ||||
| 
 | ||||
|  | @ -88,6 +92,7 @@ static SCHEMES: Once<RwLock<SchemeList>> = Once::new(); | |||
| fn init_schemes() -> RwLock<SchemeList> { | ||||
|     let mut list: SchemeList = SchemeList::new(); | ||||
|     list.insert(Box::new(*b"debug"), Arc::new(Mutex::new(Box::new(DebugScheme)))).expect("failed to insert debug: scheme"); | ||||
|     list.insert(Box::new(*b"initfs"), Arc::new(Mutex::new(Box::new(InitFsScheme::new())))).expect("failed to insert initfs: scheme"); | ||||
|     RwLock::new(list) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Jeremy Soller
						Jeremy Soller