-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathboot2.s
More file actions
776 lines (722 loc) · 20.1 KB
/
boot2.s
File metadata and controls
776 lines (722 loc) · 20.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
.code16
.globl _start
.section .text
_start:
### SEGMENTS AND POINTERS ###
stack_setup:
movw $0x9400, %ax
movw %ax, %sp
### STARTUP MESSAGES ###
startup_messages:
call clear_screen
pushw $copyright
call print_text
pushw $welcome_text
call print_text
### FAT INIT ##
# pushw $0x7cf
# call load_fat
### A20 ###
call a20_status
cmpw $1, %ax
je print_enabled
jmp print_disabled
print_enabled:
pushw $a20_line_enabled
call print_text
jmp next
print_disabled:
pushw $a20_line_disabled
call print_text
call activate_a20 # Try, and enable A20 line
call a20_status # Get A20 status
cmpw $1, %ax
jne a20_failed
a20_success:
pushw $a20_line_enabled # Print status text and continue
call print_text
jmp next
a20_failed:
pushw $a20_line_failed # If A20 line activation fails, print
call print_text # message and reboot.
call error_reboot
next:
# FAT Driver works this was only to see if driver would work with
# driver parameters and if it can load diffrent file in second stage
# bootloader
# load_sample_kernel:
# pushw $sample_kernel_name
# call find_file
# pushw $0x7c0
# pushw $0xffff
# pushw %ax
# call read_file_linear
# movw $0, %dx
# jmp 0x7c00
load_gdt:
call setup_gdt_table
lgdt gdt
pushw $gdt_ok
call print_text
print_logo:
pushw $big_logo
call print_text
pushw $info_text
call print_text
enter_cmnd_mode:
call enter_input_mode
load_idt:
pushw $idt_loading
call print_text
lidt idt
# call print_text # Ok. This does not work beacuse we already loaded new idt.
protected:
call enter_protected
loop:
jmp loop
##############
## A20 LINE ##
##############
# ABOUT:
# Tests if the A20 line is already enabled.
# We can test that by:
# 1. Write byte 0xF0 to 0x600. ds:si
# 2. Write one byte in location that is
# bigger than 0xFFFFF (1048575) -> ex.
# 0x00 to FFFF:610. It should wrap around
# if A20 line is not enabled, and write
# that valie to 0000:0600. es:di
# 3. If byte at 0000:0600 is 0x00, A20 line
# is not enabled
# 4. If byte at 0000:0600 is still 0xF0, then
# A20 is enabled
# PARAMETERS:
# REGISTERS:
# RETURNS:
# 0 if A20 line is disabled
# 1 if A20 line is enabled
# NOTES:
#
a20_status:
pushw %bp
movw %sp, %bp
xor %ax, %ax
movw %ax, %ds
movw $0x600, %si
movw $0xF0, %ds:(%si)
not %ax
movw %ax, %es
movw $0x610, %di
movw $0x00, %es:(%di)
movw $1, %ax
movw %ds:(%si), %cx
cmpw $0xF0, %cx
je end_a20_status
xor %ax, %ax
end_a20_status:
movw %bp, %sp
popw %bp
ret
# ABOUT:
# Activates A20 gate using multiple methods:
# 1. Using BIOS function.
# 1. Using INT 15 and %ax = 0x2403, check A20 gate support.
# If unsupported (%ax = 0x86 or cf set), then jump to 2.
# If supported get status, and activate A20 gate if needed.
# If function is unable to get A20 status, go to 2.
# 2. Using keyboard controller (Classical A20 way)
# 1. Write command byte 0xD1 to IO port 0x64 (PS/2 controller).
# Then write 0xDF to port 0x60 (output port),
# which will enable A20 line
# (0b11011111 - second bit sets A20 gate support
# https://wiki.osdev.org/%228042%22_PS/2_Controller)
#
# PS/2 Controller IO Ports - 0x60-0x64
# IO Port Access type Purpose
# 0x60 Read/write Data port
# 0x64 Read Status register
# 0x64 Write Command register
# Command bytes we use here:
# 0xD1 - Write next byte to Controller Output Port,
# write next byte to 0x60 PS/2 IO port
# 0xD1 and 0xD0 allow us to read and write to
# PS/2 controller
# NOTE: After every OUT (write) instruction check if buffer is empty.
# We do this by reading from 0x64 IO port (Status Register) and
# checking if bit 2 is set (0 = buffer is empty, 1 = buffer is full).
# Do this in loop until bit 1 is not 0. -> function check_buff
# 3. Use Fast A20 method. This is dangerous and not supported on every system (chip),
# As it can cause weird effects on system if not properly supported. Because of this
# we need to add code that checks if bit 1 is already set, and if we need to write
# 0x92 port, as unnecessary writing to it may lead to later problems.
# Using this as last method to try and activate A20 line.
# How: We write specific value to port 0x92 to control A20.
# Bit 0 (rw) - fast reset
# Bit 1 (rw) - Enable/disable (0/1) A20
# Bit 3 (rw) - 0/1 Power on password bytes
# (In CMOS 0x38-0x3f or 0x36-0x3f)
# Bit 6-7 (rw) - Hard disk LED OFF (00), or ON (01,10,11)
# Bit 2,4,5 var. meanings
# NOTE: Faster than Keyboard method.
# ADDITIONAL DOCS:
# https://www.win.tue.nl/~aeb/linux/kbd/A20.html
# PARAMETERS:
# REGISTERS:
# RETURNS:
# 0 if A20 line is disabled
# 1 if A20 line is enabled
# NOTES:
#
activate_a20:
pushw %bp
movw %sp, %bp
bios_int15:
# See if A20 line is supported
# (QUERY A20 GATE SUPPORT)
movw $0x2403, %ax
int $15
cmpb $0, %ah
jnz keyboard_controller # jmp. to second activation method
jc keyboard_controller
movw $0x2401, %ax # Activate A20 gate
int $15
cmpb $0, %ah
jnz keyboard_controller
jc keyboard_controller
# Check to see if A20 line is enabled
call a20_status
testw $0x01, %ax
jnz activate_end
# Otherwise go to keyboard controller method
keyboard_controller:
xor %ax, %ax # Empty %al
call check_buff
movb $0xd1, %al # Write command byte 0xD1 to IO port 0x64. (see above)
outb %al, $0x64
call check_buff
movb $0xdf, %al # Write second byte that sets bits to PS/2 controller (see above)
outb %al, $0x60
call check_buff
# Check to see if A20 line is enabled
call a20_status
testw $0x01, %ax
jnz activate_end
jmp fast_a20
# Go to fast A20 method
check_buff:
inb $0x64, %al
testb $2, %al # Bitwise AND, Checks if bit 2 is set.
# If result is 0, ZF is set to 1, otherwise to 0.
jnz check_buff
ret
fast_a20:
inb $0x92, %al
testb $0x02, %al # Read value from 0x92
jnz fast_a20_end # And see if bit 2 is set
orb $0x02, %al # If not, set bit 2, other bits, and write to 0x92.
andb $0xfe, %al
outb %al, $0x92
fast_a20_end:
# Check to see if A20 line is enabled
call a20_status # Sets return value
activate_end:
movw %bp, %sp
popw %bp
ret
# ABOUT:
# Disables A20 line.
# This is debug function. It only uses bios int15 function to disable
# A20 line. Use only for debug.
# PARAMETERS:
# REGISTERS:
# RETURNS:
# NOTES:
# This function will be implemented properly if there will be need for it.
#
disable_a20:
pushw %ax
# See if A20 line is supported
# (QUERY A20 GATE SUPPORT)
movw $0x2403, %ax
int $15
cmpb $0, %ah
jnz error_unsupported
jc error_unsupported
movw $0x2400, %ax
int $15
jc error_reboot
cmpb $0x86, %ah
je error_unsupported
popw %ax
ret
###############
## GDT TABLE ##
###############
# ABOUT: Sets up and loads GDT table
# Global descriptor table contains list of selectors, that contain
# Information with what memory locations can process access, with specific
# premissions
#
# Format of segment descriptor:
#
# 31#####################24#23####20#19#######16#15###############8#7#######################0
# # ## ## ## ## #
# # Base Address(24-31) ## Flags ## Limit ## Access byte ## Base Address (16-23) #
# # ## ## ## ## #
# ###########################################################################################
# # ## #
# # Base Address (0-15) ## Segment Limit (0-15) #
# # ## #
# ###########################################################################################
#
# INFO:
# 0-15 Segment Limit - Lower 4 bytes of the descriptors limit.
# 16-31 Base address - Lower 4 bytes of the descriptors base address
# 32-39 Base address - Middle 2 bytes of descritprors base address
# 40-47 Access byte - Bit flags defining who has access to memory
# 48-51 Segment Limit - Upper 4 bits of descriptors limit.
# 52-55 Flags - Four flags used to define segment size
# 56-63 Base address - Upper 2 bytes od descriptors base address
#
# Segment Limit - Definies maximum addresable unit
# Base address - Contains linear address where segment begins
#
# Address Content
# GDTR Offset + 0 Null
# GDTR Offset + 8 Entry 1 - Code Descriptor
# GDTR Offset + 16 Entry 2 - Data Descriptor
# ....
#
# Access Byte:
# 6 Present(Pr) - Is selector present or not (1/0)
# 5 Privilege level(Priv) - Set level(ring) of execution. 0-3
# 4 1
# 3 Excebutable(Ex) - Is memory content executable
# 2 Direction(DC) - Indicates if code can be executed from lower privelege level
# (Code Segment)
# Conforming(DC) - Indicates if segment grows down(1) or up(0) (Data seg)
# 1 Readable(RW) - Indicates if memory content can be read (1) (Code seg)
# Writable(RW) - Indicates if data can be writen to memory (1) (Data seg)
# 0 Accessed(Ac) - If Segment is accessed, this will be set to 0
#
# Flag:
# 3 Granularity(Gr) - (0) Descriptor limit is specified in bytes.
# (1) Descriptor limit is specified in blocks (4KB - we can access 4GB)
# 2 Size(Sz) - (0) 16bit protected mode, (1) 32bit protected mode
# 1,0 0 0
#
# gdt: is table containing pointer to gdt_table with 16 bit value that contains gdt_table
# size. Used for lgdt instruction
#
setup_gdt_table:
# null_descriptor:
# .zero 8
# code_descriptor: # For cs segment
# .byte 0xff, 0xff # Lower segment Limit (Limit to 4GB with 4KB blocks)
# .byte 0x00, 0x00 # 0 beacuse we want to start from 0 (Lower base)
# .byte 0x0 # Middle base
# .byte 0x9a # Access byte ()
# .byte 0xc # Flags (Gr, Sz)
# .byte 0xf # Limit
# .byte 0x00 # Base
# data_descriptor: # For ds, es, fs, gs, ss segments
# .byte 0xff, 0xff
# .byte 0x00, 0x00
# .byte 0x0
# .byte 0x92
# .byte 0xc
# .byte 0xf
# .byte 0x00
xor %ax, %ax
# xor %di, %di
movw %ax, %es
movw $0x7c00, %di
null_descriptor:
movw $0x4, %cx
rep stosw
code_descriptor:
movw $0xffff, %es:(%di)
movw $0x0000, %es:2(%di)
movb $0x00, %es:4(%di)
movb $0x9a, %es:5(%di)
movb $0xc, %es:6(%di)
movb $0xf, %es:7(%di)
movb $0x00, %es:8(%di)
addw $8, %di
data_descriptor:
movw $0xffff, %es:(%di)
movw $0x0000, %es:2(%di)
movb $0x00, %es:4(%di)
movb $0x92, %es:5(%di)
movb $0xc, %es:6(%di)
movb $0xf, %es:7(%di)
movb $0x00, %es:8(%di)
ret
gdt:
.word 24 # 3*64 bit
.long 0x700
###############
## IDT TABLE ##
###############
idt:
.word 2048
.long 0x7cc0 # (700, 708, 710, 718)
####################
## PROTECTED MODE ##
####################
# ABOUT:
#
# PARAMETERS:
# REGISTERS:
# RETURNS:
# NOTES:
#
enter_protected:
cli
movl %cr0, %eax
or $1, %eax
movl %eax, %cr0
jmp clear_prefetch_queue
nop
nop
clear_prefetch_queue:
ret
######################
## SCREEN FUNCTIONS ##
######################
# INT 10 - 17th int vector
# Interrupt handler that BIOS sets up. They provide video services ->
# Video mode (0h), cursor position (02h), get cursor position (02h)...
#
# ABOUT:
# Reads char from keyboard buffer
# INT $0x16
# PARAMETERS:
# NaN
# REGISTERS:
# %ah - Scan code of pressed down key
# %al - ASCII char of pressed down key
# RETURNS:
# %al - ASCII char
# NOTES:
read_char:
movb $0x0, %ah
int $0x16
ret
# ABOUT:
# Writes char given by parameter to screen
# INT $0x16
# PARAMETERS:
# %al = char
# REGISTERS:
# %al - Char
# %bh - Page number
# %bl - Color
# RETURNS:
# %al - ASCII char
# NOTES:
write_char:
pushw %bx
movb $0xe, %ah
movb $0x0, %bh
movb $0x07, %bl
int $0x10
popw %bx
ret
# ABOUT:
# Enters input mode. Programs waits for char input, echoes that input to screen,
# Stores char to buffer and sends that buffer to command parse.
# INT $0x16
# PARAMETERS:
# NaN
# REGISTERS:
# NaN
# RETURNS:
# NaN
# NOTES:
enter_input_mode:
jmp go_new_line
continue_input:
mov $cmnd_buffer, %di
check_input:
call read_char
cmpb $0xd, %al
je end_check_input
cmpb $0x8, %al
je bs_handler
store_buffer:
movb %al, (%di)
incw %di
call write_char
jmp check_input
bs_handler:
cmpw $cmnd_buffer, %di
je check_input
call write_char
movb $0x20, %al
call write_char
movb $0x8, %al
call write_char
decw %di
movw $0, (%di)
jmp check_input
end_check_input:
# Write null to buffer
movw $0, (%di)
# Write commmand info (debug)
# This is cmd parse is only for testing,
# Will rewrite later
pushw $cmnd_buffer
pushw $command_reboot
call cmprstr
cmpb $1, %ah
movb %ah, %al
je error_reboot
pushw $cmnd_buffer
pushw $command_help
call cmprstr
cmpb $1, %ah
je print_help
pushw $cmnd_buffer
pushw $command_about
call cmprstr
cmpb $1, %ah
je print_about
pushw $cmnd_buffer
pushw $command_boot
call cmprstr
cmpb $1, %ah
je boot_seq
# debug
pushw $command_not_found
call print_text
pushw $cmnd_buffer
call print_text
jmp go_new_line
boot_seq:
jmp go_new_line
print_about:
pushw $about_text
call print_text
jmp go_new_line
print_help:
pushw $help_text
call print_text
# Go to new line and write >
go_new_line:
pushw $command_line
call print_text # Memory leaks. Fix me
jmp continue_input
ret
# ABOUT:
# Prints text from given address until null char is hit.
# INT $0x10
# PARAMETERS:
# 1. Parameter 1 - Addres to start of the text to check
# 2. Parameter 2 - Address to text to which to compare 1. parameter
# REGISTERS:
# NaN
# RETURNS:
# NOTES:
cmprstr:
pushw %bp
movw %sp, %bp
pushw %di
pushw %bx
setup:
movw 4(%bp), %di
movw 6(%bp), %bx
loop_chars:
movb (%di), %al
cmpb %al, (%bx)
# call write_char
jne not_eq
incw %di
incw %bx
cmpb $0, %al
je char_end_eq
jmp loop_chars
not_eq:
notb %ah
jmp char_end
char_end_eq:
movb $1, %ah
char_end:
popw %bx
popw %di
movw %bp, %sp
popw %bp
ret
# ABOUT:
# Prints text from given address until null char is hit.
# INT $0x10
# PARAMETERS:
# 1. Parameter 1 - Address to data to print <-- 4(%bp)
# REGISTERS:
# %ah - 0x0e - function code
# %al - Caracter to output
# %bh - Page number
# %bl - Color
# %ax - Printed characters
# RETURNS:
# Number of writen bytes in %ax
# NOTES:
#
print_text: # Clear parameter from stack on exit to mitigate memory
# leak
pushw %bp
# pushw %di
# pushw %bx
movw %sp, %bp
movw 4(%bp), %di
xor %ax, %ax # Empty counter register
# Used for counting chars.
movw %ax, %es
print_loop:
movb %es:(%di), %al
cmpb $0, %al
je print_end
movb $0x0e, %ah
movb $0x00, %bh
movb $0x07, %bl
int $0x10
incw %di
jmp print_loop
print_end:
movw 4(%bp), %ax # Get original address
subw %ax, %di # Sub final address from orig. address
movw %di, %ax # Move result to %ax for return value.
# popw %bx
# popw %di # Restore registers
# Return from the function and perm parameter cleanup.
# (%bp) -> bp
# 2(%bp) -> ret
# 4(%bp) -> par 1.
# 6(%bp) -> par 2.
# 8(%bp) <------ thi
movw 2(%bp), %bx # Move return address to temp. reg.
movw %bp, %sp # Restore stack
popw %bp
addw $8, %sp # Clear parameters
pushw %bx # Emulate return addr. by pushin addr. to stack
ret # Return
# ABOUT:
# Clears screen
# INT $0x10
# PARAMETERS:
#
# REGISTERS:
# %ah - 0x6 - Function code to scroll up
# (0x7 for down)
# %al - Lines to scroll (down or up) if 0 (clear),
# then ch, cl, dh, dl are used
# %bh - Background color -> high four bits are for background,
# and for low are for foregorund
# (see BIOS color attributes)
# %ch - Upper row number
# %cl - Left column number
# %dh - Lower row number
# %dl - Right column number
#
# RETURNS:
#
# NOTES:
#
clear_screen:
pushw %bp
movw %sp, %bp
movb $0x07, %ah
movb $0x00, %al
movb $0x07, %bh
xor %cx, %cx
movb $0x19, %dh
movb $0x50, %dl
int $0x10
movw %bp, %sp
popw %bp
ret
## FILES ##
list_files:
pushw $files
call print_text
ret
## ERROR SUBROUTINES ##
#
# ABOUT:
# If error while calling bios function is 0x86 or 0x80
# jmp to error_unsuported, which will print that function
# is not supported, and will continue down to error_reboot.
# If carry flag is set, jmp to error_reboot,
# which will print message, and wait for user input (int 0x16, ah 0x00),
# and it will then reboot the system.
#
error_unsupported:
pushw $error_text
call print_text # Print function error text
subw $2, %sp
error_reboot:
pushw $error_text
call print_text # Print error text
subw $2, %sp
xor %ax, %ax # ah - 0x00 and it 0x16 for reading keyboard scancode
int $0x16 # Contines executing after any key on keyboard
# has been pressed
jmp $0xffff, $0000 # Jumps to reset vector, and reboots pc
# FFFF * 16 + 0 = FFFF0 ->
# 1048560 - 16 bytes below 1mb
.section .data
big_logo:
.ascii "\n\n\rO OOOOO O O O OO OOOOOO OOOOO OOOOOO OOOOOO OOOOO
\rO O OO O O OO OO OO O OO O O O O O
\rO O O O O OOOO OOOO OOOOO O O O O O
\rO O O OO O OO OO O OO O O O O O
\rO O O O O OO OO OO O O O O O O O
\rOOOOOO OOOOO O O O OO OOOOOO OOOOOO OOOOOO OOOOOO O
\r--------------------------------------------------------------------------\n\n\n\n\n\0"
welcome_text:
.ascii "Welcome to LinksBoot!\n\rBooting...\n\0"
copyright:
.ascii "CopyRight Xunillen 2022. GPL license.\n\r\0"
info_text:
.ascii "\n\rTo see all available commands, type 'help'.\0"
a20_line_enabled:
.ascii "\n\rA20 Line ENABLED\0"
a20_line_disabled:
.ascii "\n\rA20 Line DISABLED\0"
a20_line_failed:
.ascii "\n\rA20 Line activation failed...\0"
a20_line_fast:
.ascii "\n\rUsing FAST A20 method...\0"
gdt_ok:
.ascii "\n\rGDT table OK\0"
idt_loading:
.ascii "\n\rLoading IDT table...\0"
error_uns_text:
.ascii "\n\rFunction not supported, or is invalid.\0"
error_text:
.ascii "\n\rBoot error... Press any key to reboot.\0"
files:
.ascii "\n\rFiles:\0"
sample_kernel_name:
.ascii "KERNEL01IMG"
command_not_found:
.ascii "\n\rCommand not found: \0"
command_line:
.ascii "\n\n\r|> \0"
command_reboot:
.ascii "reboot\0"
command_help:
.ascii "help\0"
command_boot:
.ascii "boot\0"
command_about:
.ascii "about\0"
about_text:
.ascii "\n\rLinksBoot is simple and fast bootloader with snapshot feature.\n\rCopyRight Xunillen 2022\0"
help_text:
.ascii "\n\rhelp - Lists all available commands with small description on what they do
\rabout - About this bootloader
\rreboot - Reboots computer
\rir - Lists all registers with their values
\rboot - Boots specified file (kernel). Without parameter, LinksBoot boots default file 'KERNEL01.IMG'\n\n\0"
.lcomm cmnd_buffer, 256