1
1
#![ no_std]
2
+ #![ no_main]
2
3
#![ feature( abi_x86_interrupt) ]
4
+ #![ feature( custom_test_frameworks) ]
5
+ #![ test_runner( crate :: test_runner) ]
6
+ #![ reexport_test_harness_main="test_main" ]
3
7
4
8
extern crate alloc;
5
9
6
10
use alloc:: string:: String ;
7
- use core:: arch:: asm;
11
+ use core:: { arch:: asm, panic :: PanicInfo } ;
8
12
9
13
pub mod boot;
10
14
pub mod devices;
@@ -26,11 +30,13 @@ pub fn init() {
26
30
27
31
let mut vfs = fs:: vfs:: VFS :: new ( None ) ;
28
32
fs:: ramfs:: init ( & mut vfs) ;
33
+
29
34
print_startup_message ( & mut vfs) ;
30
35
31
- let mut executor = crate :: task:: executor:: Executor :: new ( ) ;
32
- let _ = executor. spawn ( crate :: task:: Task :: new ( devices:: keyboard:: trace_keypresses ( ) ) ) ;
33
- executor. run ( ) ;
36
+ // Issue#30: Commented out for now as the code doesn't run past this section. Will return it back.
37
+ // let mut executor = crate::task::executor::Executor::new();
38
+ // let _ = executor.spawn(crate::task::Task::new(devices::keyboard::trace_keypresses()));
39
+ // executor.run();
34
40
35
41
//vfs.unmount_fs();
36
42
}
@@ -42,16 +48,16 @@ fn print_startup_message(vfs: &mut fs::vfs::VFS) -> [u8; 128] {
42
48
Ok ( vnode) => match vfs. read_file ( & vnode, & mut buffer, 0 ) {
43
49
Ok ( _bytes_read) => { }
44
50
Err ( err) => {
45
- error ! ( "Error reading file: {}\n " , err) ;
51
+ error ! ( "Error reading file: {}" , err) ;
46
52
}
47
53
} ,
48
54
Err ( err) => {
49
- error ! ( "File not found: {}\n " , err) ;
55
+ error ! ( "File not found: {}" , err) ;
50
56
}
51
57
}
52
58
53
59
info ! (
54
- "Hexium OS kernel v{} succesfully initialized at {}\n " ,
60
+ "Hexium OS kernel v{} succesfully initialized at {}" ,
55
61
env!( "CARGO_PKG_VERSION" ) ,
56
62
unsafe { rtc:: read_rtc( ) }
57
63
) ;
@@ -72,3 +78,64 @@ pub fn hlt_loop() -> ! {
72
78
}
73
79
}
74
80
}
81
+
82
+ pub fn test_panic_handler ( info : & PanicInfo ) -> ! {
83
+ serial_println ! ( "[failed]" ) ;
84
+ serial_println ! ( "Error: {}" , info) ;
85
+ exit_qemu ( QemuExitCode :: Failed ) ;
86
+ loop { }
87
+ }
88
+
89
+ pub fn test_runner ( tests : & [ & dyn Testable ] ) {
90
+ serial_println ! ( "Running {} tests" , tests. len( ) ) ;
91
+
92
+ for test in tests {
93
+ test. run ( ) ;
94
+ }
95
+
96
+ exit_qemu ( QemuExitCode :: Success ) ;
97
+ }
98
+
99
+
100
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
101
+ #[ repr( u32 ) ]
102
+ pub enum QemuExitCode {
103
+ Success = 0x10 ,
104
+ Failed = 0x11 ,
105
+ }
106
+
107
+ pub fn exit_qemu ( exit_code : QemuExitCode ) {
108
+ use x86_64:: instructions:: port:: Port ;
109
+
110
+ unsafe {
111
+ let mut port = Port :: new ( 0xf4 ) ;
112
+ port. write ( exit_code as u32 ) ;
113
+ }
114
+ }
115
+
116
+ pub trait Testable {
117
+ fn run ( & self ) ;
118
+ }
119
+
120
+ impl < T > Testable for T
121
+ where T : Fn ( ) ,
122
+ {
123
+ fn run ( & self ) {
124
+ serial_print ! ( "{}...\t " , core:: any:: type_name:: <T >( ) ) ;
125
+ self ( ) ;
126
+ serial_println ! ( "[ok]" ) ;
127
+ }
128
+ }
129
+
130
+ #[ cfg( test) ]
131
+ #[ unsafe( no_mangle) ]
132
+ unsafe extern "C" fn kmain ( ) -> ! {
133
+ test_main ( ) ;
134
+ loop { }
135
+ }
136
+
137
+ #[ cfg( test) ]
138
+ #[ panic_handler]
139
+ fn panic ( info : & PanicInfo ) -> ! {
140
+ test_panic_handler ( info)
141
+ }
0 commit comments