1 ; =============================================================================
2 ; BareMetal -- a 64-bit OS written in Assembly for x86-64 systems
3 ; Copyright (C) 2008-2011 Return Infinity -- see LICENSE.TXT
5 ; COMMAND LINE INTERFACE
6 ; =============================================================================
14 mov rsi
, prompt
; Prompt for input
15 mov bl, 0x09 ; Black background, Light Red text
16 call os_print_string_with_color
18 mov rdi
, cli_temp_string
19 mov rcx
, 250 ; Limit the input to 250 characters
21 call os_print_newline
; The user hit enter so print a new line
22 jrcxz os_command_line
; os_input_string stores the number of charaters received in RCX
25 call os_string_parse
; Remove extra spaces
26 jrcxz os_command_line
; os_string_parse stores the number of words in RCX
27 mov byte [cli_args
], cl ; Store the number of words in the string
29 ; Copy the first word in the string to a new string. This is the command/application to run
31 mov rsi
, cli_temp_string
32 mov rdi
, cli_command_string
33 push rdi
; Push the command string
37 cmp al, ' ' ; End of the word
39 cmp al, 0x00 ; End of the string
41 cmp rcx
, 13 ; More than 12 bytes
47 stosb ; Terminate the string
49 ; At this point cli_command_string holds at least "a" and at most "abcdefgh.ijk"
51 ; Break the contents of cli_temp_string into individual strings
52 mov rsi
, cli_temp_string
55 call os_string_change_char
57 pop rsi
; Pop the command string
58 call os_string_uppercase
; Convert to uppercase for comparison
60 mov rdi
, cls_string
; 'CLS' entered?
61 call os_string_compare
64 mov rdi
, dir_string
; 'DIR' entered?
65 call os_string_compare
68 mov rdi
, ver_string
; 'VER' entered?
69 call os_string_compare
72 mov rdi
, date_string
; 'DATE' entered?
73 call os_string_compare
76 mov rdi
, exit_string
; 'EXIT' entered?
77 call os_string_compare
80 mov rdi
, help_string
; 'HELP' entered?
81 call os_string_compare
84 mov rdi
, node_string
; 'NODE' entered?
85 call os_string_compare
88 mov rdi
, time_string
; 'TIME' entered?
89 call os_string_compare
92 mov rdi
, debug_string
; 'DEBUG' entered?
93 call os_string_compare
96 mov rdi
, reboot_string
; 'REBOOT' entered?
97 call os_string_compare
100 mov rdi
, testzone_string
; 'TESTZONE' entered?
101 call os_string_compare
104 ; At this point it is not one of the built-in CLI functions. Prepare to check the filesystem.
106 call os_string_find_char
; Check for a '.' in the string
108 jne full_name
; If there was a '.' then a suffix is present
110 ; No suffix was present so we add the default application suffix of ".APP"
112 call os_string_length
114 jg fail
; If the string is longer than 8 chars we can't add a suffix
116 mov rdi
, cli_command_string
117 mov rsi
, appextension
; '.APP'
118 call os_string_append
; Append the extension to the command string
120 ; cli_command_string now contains a full filename
122 mov rsi
, cli_command_string
123 mov rdi
, programlocation
; We load the program to this location in memory (currently 0x00100000 : at the 2MB mark)
124 call os_file_read
; Read the file into memory
125 jc fail
; If carry is set then the file was not found
127 mov rax
, programlocation
; 0x00100000 : at the 2MB mark
128 xor rbx
, rbx
; No arguements required (The app can get them with os_get_argc and os_get_argv)
129 call os_smp_enqueue
; Queue the application to run on the next available core
130 jmp exit
; The CLI can quit now. IRQ 8 will restart it when the program is finished
132 fail: ; We didn't get a valid command or program name
133 mov rsi
, not_found_msg
154 mov rdi
, cli_temp_string
156 call os_file_get_list
161 mov rdi
, cli_temp_string
163 call os_get_date_string
165 call os_print_newline
169 mov rdi
, cli_temp_string
171 call os_get_time_string
173 call os_print_newline
177 jmp os_command_line
; Nothing here yet...
181 xchg bx, bx ; Bochs Magic Breakpoint
183 ; call os_ethernet_avail
184 ; call os_debug_dump_rax
186 ; mov rdi, cli_temp_string
189 ; call os_input_string
190 ; call os_file_get_size
192 ; call os_print_newline
193 ; call os_debug_dump_rax
196 ; xor eax, eax ; Out-of-order execution can cause RDTSC to be executed later than expected
197 ; cpuid ; Execute a serializing instruction to force every preceding instruction to complete before allowing the program to continue
200 ; Benchmark code start
203 ; mov [rsp + 0x20], rax
204 ; mov [rsp + 0x18], rax
205 ; mov [rsp + 0x10], rax
206 ; mov [rsp + 0x8], rax
209 ; mov rax, [rsp + 0x8]
210 ; mov rax, [rsp + 0x10]
211 ; mov rax, [rsp + 0x18]
212 ; mov rax, [rsp + 0x20]
226 ; Benchmark code finish
227 ; xor eax, eax ; Out-of-order execution can cause RDTSC to be executed later than expected
228 ; cpuid ; Execute a serializing instruction to force every preceding instruction to complete before allowing the program to continue
232 ; call os_debug_dump_eax
233 ; call os_print_newline
237 call os_print_char_with_color
239 call os_print_char_with_color
242 call os_print_char_with_color
244 call os_print_char_with_color
247 call os_print_char_with_color
249 call os_print_char_with_color
252 call os_print_char_with_color
254 call os_print_char_with_color
257 call os_print_char_with_color
259 call os_print_char_with_color
262 call os_print_char_with_color
264 call os_print_char_with_color
267 call os_print_char_with_color
269 call os_print_char_with_color
272 call os_print_char_with_color
274 call os_print_char_with_color
275 call os_print_newline
278 call os_print_char_with_color
280 call os_print_char_with_color
283 call os_print_char_with_color
285 call os_print_char_with_color
288 call os_print_char_with_color
290 call os_print_char_with_color
293 call os_print_char_with_color
295 call os_print_char_with_color
298 call os_print_char_with_color
300 call os_print_char_with_color
303 call os_print_char_with_color
305 call os_print_char_with_color
308 call os_print_char_with_color
310 call os_print_char_with_color
313 call os_print_char_with_color
315 call os_print_char_with_color
316 call os_print_newline
320 ; call os_debug_dump_rax
322 ; call os_mem_get_free
324 ; call os_debug_dump_rax
328 ; mov ax, word [os_MemAmount]
329 ; shr ax, 1 ; Divide actual memory by 2 (RAX now holds total pages)
330 ; call os_debug_dump_rax
331 ; call os_print_newline
332 ; mov rcx, 2 ; 2 pages = 4 MiB
333 ; call os_mem_allocate
334 ; call os_debug_dump_rax
335 ; call os_print_newline
338 ; call os_get_time_data
353 test al, 00000010b ; Wait for an empty Input Buffer
356 out 0x64, al ; Send the reboot call to the keyboard controller
360 call os_get_argc
; Check the argument number
362 je debug_dump_reg
; If it is only one then do a register dump
364 cmp al, 3 ; Did we get at least 3?
365 jl noamount
; If not no amount was specified
367 call os_get_argv
; Get the amount of bytes to display
368 call os_string_to_int
; Convert to an integer
372 call os_get_argv
; Get the starting memory address
373 call os_hex_string_to_int
376 call os_debug_dump_mem
377 call os_print_newline
382 call os_debug_dump_reg
389 help_text
db 'Built-in commands: CLS, DATE, DEBUG, DIR, HELP, REBOOT, TIME, VER', 13, 0
390 not_found_msg
db 'Command or program not found', 13, 0
391 version_msg
db 'BareMetal OS ', BAREMETALOS_VER
, 13, 0
393 cls_string
db 'CLS', 0
394 dir_string
db 'DIR', 0
395 ver_string
db 'VER', 0
396 date_string
db 'DATE', 0
397 exit_string
db 'EXIT', 0
398 help_string
db 'HELP', 0
399 node_string
db 'NODE', 0
400 time_string
db 'TIME', 0
401 debug_string
db 'DEBUG', 0
402 reboot_string
db 'REBOOT', 0
403 testzone_string
db 'TESTZONE', 0
406 ; =============================================================================