3 // (c) 2004 Bryan Chafy, This program is released under the GPL
5 // LLShell, A low level interactive debug shell
6 // Designed to be an interactive shell that operates with zero
7 // system resources. For example at initial boot.
9 // to use, jump to label "low_level_shell"
10 // set %esp to the return address for exiting
13 #define UART_BASEADDR $0x3f8
14 #define resultreg %esi
15 #define subroutinereg %edi
16 #define freqtime $2193 // 1.93 * freq
17 #define timertime $6000
24 .string "\r\n! Low Level Shell (LLShell) (c)2004 Bryan Chafy \r\n\r\n"
28 .string "bad command\r\n"
30 .string "sorry, not yet implemented\r\n"
32 .string "\r\nList of commands:\r\n \
33 \r\nbeep -- pc speaker beep \
34 \r\nrst (or RST) -- reset \
35 \r\nout(b,w,l) <val> <port> -- raw out val at port \
36 \r\nin(b,w,l) <port> -- show raw port value \
37 \r\njmp <address> -- jmp to address (llshell addr is in eax) \
38 \r\ncall <address> -- funcion call (assumes a working stack) \
39 \r\ncli -- clear interrupts \
40 \r\nsti -- enable interrupts \
41 \r\npush <value> -- push value onto stack \
42 \r\npop -- pop from stack and display \
43 \r\nwm(b,w,l) <addr> <val> -- write mem \
44 \r\ndm <addr> <lines> -- dump mem \
45 \r\nmcp <src> <dst> <size> -- mem copy \
46 \r\nmpat <pat> <dst> <size> -- mem pattern \
47 \r\nmemt <begin> <end> -- memory test \
48 \r\npcir(b,w,l) <loc> -- pci read config \
49 \r\npciw(b,w,l) <loc> <val> -- pci write config \
50 \r\ndl <addr> <size> -- memory download (display xor cheksum at completion) \
51 \r\ncram <addr> <size> -- enable cache to be ram (experimental) \
52 \r\nbaud <val> -- change baudrate (not yet implemented) \
53 \r\nexit -- exit shell \
54 \r\nAll values in hex (0x prefixing ok) \
63 //ASSUME CS:@CODE, DS:@DATA
71 mov $preamble,subroutinereg
74 mov $welcome,resultreg
75 mov $readcommand,subroutinereg
80 mov $rcmd,subroutinereg
84 mov $readcommand,subroutinereg
88 mov UART_BASEADDR+5,%dx
94 in %dx,%al //char in al
98 mov UART_BASEADDR+5,%dx
103 mov UART_BASEADDR,%dx
105 out %al,%dx // output char
113 cmp $0x20,%al //space
179 jz dodl // download to mem <loc> <size>
181 jz jmpto // jump to location (eax holds return addr)
183 jz baud // change baudrate
185 jz doint // trigger an interrupt
187 jz callto // call assumes memory
189 jz dopush // assumes mem
191 jz dopop // assumes mem
193 jz cram // cache ram trick <location> <size>
195 jz mcp // mem copy <src> <dst> <size>
204 mov $badcmd,resultreg
205 mov $readcommand,subroutinereg
212 mov UART_BASEADDR+5,%dx
217 mov UART_BASEADDR,%dx
222 mov UART_BASEADDR+5,%dx
227 mov UART_BASEADDR,%dx
229 out %al,%dx // output char
239 cmp $0x20,%al //space
273 // ebx,ecx,ebp,esp(?)
277 mov $ramtest,resultreg
278 mov $test1a,subroutinereg
281 mov $welcome,resultreg
282 mov $readcommand,subroutinereg
287 movl $dmem1a, subroutinereg
290 mov resultreg,%ebx // address
291 movl $dmem1b, subroutinereg
294 mov resultreg,%ecx // length
298 mov $daddr1,subroutinereg
301 mov $spaces,resultreg
302 mov $startshowm,subroutinereg
307 mov $showm1,subroutinereg
312 mov $showm2,subroutinereg
317 mov $showm3,subroutinereg
322 mov $showa0,subroutinereg
328 mov $showa1,subroutinereg
329 jmp displayasciilinear
333 mov $showa2,subroutinereg
334 jmp displayasciilinear
338 mov $showa3,subroutinereg
339 jmp displayasciilinear
343 mov $doneshow,subroutinereg
344 jmp displayasciilinear
347 mov $doneshow1,subroutinereg
360 movl $outb1a, subroutinereg
364 movl $outb1b, subroutinereg
374 movl $outw1a, subroutinereg
378 movl $outw1b, subroutinereg
388 movl $outd1a, subroutinereg
392 movl $outd1b, subroutinereg
401 movl $wmemba, subroutinereg
405 movl $wmembb, subroutinereg
413 movl $wmemwa, subroutinereg
417 movl $wmemwb, subroutinereg
425 movl $wmemla, subroutinereg
429 movl $wmemlb, subroutinereg
438 movl $inb1a, subroutinereg
445 mov $readcommand,subroutinereg
450 movl $inw1a, subroutinereg
457 mov $readcommand,subroutinereg
462 movl $ind1a, subroutinereg
468 mov $readcommand,subroutinereg
472 movl $jmp1a, subroutinereg
475 mov $readcommand,%eax
479 movl $call1a, subroutinereg
482 mov $readcommand,%eax
487 movl $push1a, subroutinereg
495 movl $int1a, subroutinereg
499 // need to lookup int table?
508 movl $readcommand, subroutinereg
522 // resultreg= pointer to string terminated by \0
527 mov UART_BASEADDR+5,%dx
532 mov UART_BASEADDR,%dx
534 out %al,%dx // output char
564 mov UART_BASEADDR+5,%dx
569 mov UART_BASEADDR,%dx
571 out %al,%dx // output char
603 mov UART_BASEADDR+5,%dx
608 mov UART_BASEADDR,%dx
610 out %al,%dx // output char
666 mov $readcommand,subroutinereg
670 movl $memt1, subroutinereg
674 movl $memt2, subroutinereg
679 mov $readcommand,%esp // internal to linux bios
683 movl $pcirb1, subroutinereg
690 mov $readcommand,subroutinereg
694 movl $pcirw1, subroutinereg
701 mov $readcommand,subroutinereg
705 movl $pcirl1, subroutinereg
709 PCI_READ_CONFIG_DWORD
711 mov $readcommand,subroutinereg
718 movl $pciwb1, subroutinereg
722 movl $pciwb2, subroutinereg
727 PCI_WRITE_CONFIG_BYTE
731 movl $pciww1, subroutinereg
735 movl $pciww2, subroutinereg
740 PCI_WRITE_CONFIG_WORD
744 movl $pciwl1, subroutinereg
748 movl $pciwl2, subroutinereg
753 PCI_WRITE_CONFIG_DWORD
757 //likely not working. Just testing for now
758 movl $cram1, subroutinereg
762 movl $cram1, subroutinereg
768 and $0x9fffffff,%eax // also try 0x0fff, 0x2ff(write back)...
782 movl $dl1, subroutinereg
786 movl $dl2, subroutinereg
790 mov resultreg,subroutinereg
793 mov UART_BASEADDR+5,%dx
798 mov UART_BASEADDR,%dx
804 mov subroutinereg,%ecx
814 mov $readcommand,subroutinereg
820 mov $readcommand,subroutinereg
824 movl $mcp1, subroutinereg
828 movl $mcp2, subroutinereg
832 movl $mcp3, subroutinereg
846 movl $pat1, subroutinereg
850 movl $pat2, subroutinereg
854 movl $pat3, subroutinereg
869 RETSP // if there's no stack yet, caller must set %esp manually
870 // RET_LABEL(low_level_shell)
875 movl $sys_IOPL, %eax # system-call ID-number
876 movl $3, %ebx # new value for IO0PL
877 int $0x80 # enter the kernel