Important
You may have to give the -stall options to simics, depending on the current workload of the machine you are running on.
Without it you can experience some long error messages when starting simics (but with it simics will run slower).
host$ ./simics -stall targets/malta/malta-linux-common.simics
Simics Introduction Lab
The purpose of this lab is to get you started with Simics, and show you some of the basic debug functionality. We assume that you start by installing Simics as detailed in the installation guide.
Run Simics with Linux on a MIPS machine
Now that you're Simics installation is completed, let's take the simulator for a spin. We will do this by running a Montavista Linux on Simics/MIPS.
- Change directory to your simics workspace:
host$ cd ~/simics-workspace
- Start simics, using the simics script. As the argument, give the name of the startup script (.simics file) that you will use to start Simics. In our case, the startup file is called targets/malta/malta-linux-common.simics.
host$ ./simics targets/malta/malta-linux-common.simics
- If this fails to work, please see the clarifications and FAQ page for more information.
- When Simics starts, two windows should open on the side (one text terminal and one small window representing the LCD display of the simulated Malta board). In the main window, you will be greeted by a Simics startup message, and finally you will arrive at the Simics command prompt:
Checking out a license... done: academic license. +----------------+ Copyright 1998-2006 by Virtutech, All Rights Reserved | Virtutech | Version: Simics 3.0.24 | Simics | Build: 1368 Host: v9-sol8-64 +----------------+ www.simics.com "Virtutech" and "Simics" are trademarks of Virtutech AB Use of this software is subject to appropriate license. Type 'copyright' for details on copyright. Type 'help help' for info on the on-line documentation. simics>
- Start booting Linux by typing the command c, for "continue":
simics> c
- Now, you should be getting output in the text terminal. After a (short) while, the simulated Montavista Linux will arrive at its command-prompt:
- You should also see a scrolling text in the LCD window:
- In the main Simics window you will also see a bunch of warnings about memory accesses. in the main Simics window).
- Try som Linux commands at this prompt, such as ls, cd, pwd. Use cat to look at the contents of files. To see what the Linux thinks that it is running from, try cat /proc/cpuinfo:
sh-2.04# cat /proc/cpuinfo cpu : MIPS cpu model : R4310 V0.0 system type : unknown unknown BogoMIPS : 49.86 byteorder : little endian unaligned accesses : 0 wait instruction : no microsecond timers : no extra interrupt vector : yes hardware watchpoint : yes VCED exceptions : not available VCEI exceptions : not available
- To get back to the Simics prompt, we need to stop the simulation. Bring the Simics console to the front and press ctrl-C. This should get you back to the Simics prompt. When we stop simulation in this manner, Simics will show you the instruction where execution was stopped, with both its virtual (v:) and physical address shown (p:):
[cpu0] v:0x8010870c p:0x0010870c beq v0,zero,0x8010871c simics>
Using the Simics command prompt
From the Simics command prompt, you have a lot of powerful commands available. Here we will walk you through the most basic information; for more commands and tips on debugging, look at the debug tips page.
- Simics is an object-oriented environment: the entire simulated machine is built up from a number of objects, typically one for each device, processor, or memory in the system. Plus some for the basic functionality provided by Simics. All objects have commands defined for them, some more and some less. To see all objects in the current simulation, use the command list-objects:
simics> list-objects Component Class Object --------------------------------------- <malta-system> system_cmp0 <south-bridge-piix4> south_bridge_cmp0 <std-super-io> sio_cmp0 <std-text-console> text_console_cmp0 Class Object | Class Object --------------------------------+-------------------------------- <DS12887> rtc0 | <malta> malta <GT64120-pci> gt_pci_0_0 | <memory-space> cbus_space <GT64120-pci> gt_pci_0_1 | <memory-space> pci_bus0_conf <GT64120-pci> gt_pci_1_0 | <memory-space> pci_bus0_io <GT64120-pci> gt_pci_1_1 | <memory-space> pci_bus0_mem <GT64120> gt | <memory-space> pci_bus1_conf <ISA> isa0 | <memory-space> pci_bus1_io <NS16550> com1 | <memory-space> pci_bus1_mem <NS16550> com2 | <memory-space> phys_mem <apm> apm0 | <mips-4kc> cpu0 <context> primary_context | <pci-bus> pci_bus0 <floppy-drive> fd0 | <pci-bus> pci_bus1 <floppy-drive> fd1 | <piix4_ide> pci_to_ide0 <hostfs> hfs | <piix4_isa> pci_to_isa0 <i8042> kbd0 | <piix4_power> power0 <i82077> flp0 | <piix4_usb> pci_to_usb0 <i8237x2> dma0 | <port-space> isa_bus0 <i8254> pit0 | <python> python <i8259x2> pic0 | <ram> ram <ide> ide0 | <recorder> rec0 <ide> ide1 | <rom> rom <image> ram_image | <text-console> con0 <image> rom_image | <text-console> display
- Noteworthy objects are cpu0, the processor, and com1, the serial port connected to the con0 console. Try the command help on these objects to see the command available for each.
simics> help con0 Class text-console Provided by xterm-console Class Hierarchy conf-object -> conf-object -> text-console Interfaces Implemented keyboard_console, event_poster, extended_serial, serial_device Description The text-console class provides a text user interface to the simulated machine's console. Command List Commands break set a string to break on capture-start capture output to file capture-stop stop output capture to file close close console window disable-quiet enable output redirection disable-window deprecated --- hide console window enable-quiet disable output redirection enable-window deprecated --- show console window info print information about the device input send string to a console input-file input a file into a console kbd-abort send a keyboard abort signal list-break-strings list all strings the console will break on no-window deprecated --- show/hide console window open open console window playback-start start traffic generator playback-stop stop traffic generation quiet toggle console output redirection read-only toggle read-only mode record-start start recording of output on the console record-stop stop recoding of output on the console status print status of the device switch-to-serial-link replace text-console with serial link switch-to-server-console replace text console with server console unbreak stop breaking on string unbreak-id remove a breakpoint wait-for-string wait for a string in a script branch Attributes Attributes inherited from class conf-object attributes, classname, component, iface, name, object_id, queue Attributes inherited from class conf-object attributes, classname, component, iface, name, object_id, queue Attributes declared in text-console abort, add_title, application, application_args, bg_color, break_string, break_string_id, char_1c_is_abort, console_trace, device, environment, fg_color, height, history, history_length, history_next, history_wrap, input , input_buf, input_delayed, input_next, kbd_event_queue, link, next_char, no_window, output_file, output_timeout, quiet, read_only, recorded_string, recording, scrollback, scrollbar, title, trace_file, unbreak_id, unbreak_string, use_xterm_args, vt102_emulation, vt_contents, vt_demo, vt_height, vt_redraw, vt_state, vt_width, width, win32_font, write_delayed, x11_font, x11_fontbold, xterm_args
- To look at the code we are about execute, use the da (disassemble) command. To look at the location from the current program counter and on, we will use the short form "%pc":
simics> da %pc v:0x8010870c p:0x0010870c beq v0,zero,0x8010871c
- Looking at a single instruction is not very useful, however. There are better ways of doing things, and to find out about them, use the Simics help command:
simics> help da [... output from Simics ...]
- Note the "count" parameter that can be given to the command. By specifying this, we can disassemble more instructions:
simics> da %pc 10 v:0x8010870c p:0x0010870c beq v0,zero,0x8010871c v:0x80108710 p:0x00108710 nop v:0x80108714 p:0x00108714 jalr ra,v0 v:0x80108718 p:0x00108718 nop v:0x8010871c p:0x0010871c lw v0,20(gp) v:0x80108720 p:0x00108720 beq v0,zero,0x80108704 v:0x80108724 p:0x00108724 nop v:0x80108728 p:0x00108728 jal 0x80111ddc v:0x8010872c p:0x0010872c nop v:0x80108730 p:0x00108730 jal 0x801208b0
- It is often quite useful to know how many instructions have been executed. Since Simics is deterministic, a bug in the execution will appear at the same time each time a program is executed (typically, each time you start a certain build of your operating system from scratch). To see the current time, use the command ptime:
simics> ptime processor steps cycles time [s] cpu0 14098153963 14098153963 281.963
- To get some more detailed information on the execution up to this point, use the print-statistics command for cpu0 (note that you can use tab-completion to quickly type commands):
simics> cpu0.print-statistics Statistics for cpu cpu0 User Supervisor Total Description 12386707 14085767256 14098153963 instructions executed 0 7867685 7867685 I/O read operations 0 6936872 6936872 I/O write operations
- We can use the Simics command-line to provide input to the simulated machine. This is useful to script startup and demo sequences, and test input and output. If, for example, we want to do an ls command in the simulated Linux, we can do it the following way from the Simics command-line (you need to continue the simulation for anything to happen, as the simulated machine needs to accept the input):
simics> con0.input "ls\n" simics> c
- That's the end of this part of the lab. To quit Simics, press ctrl-C to get back to prompt (unless you are already at prompt), and give the command quit to quit Simics:
simics> quit Simics license checked in! host$
Simics breakpoints during OS boot
The previous step will have taught you how to start and stop Simics, and given a flavor of how it is working with Simics. Now, we'll look more into how Simics can be used to investigate the boot process of an operating system.
- Start Simics again just like you did before (with the Linux setup).
- Set a breakpoint on accesses to the malta device, which handles the LCD display (the 8-letter window with red letters). This is done using the break-io command. Note that you do not need to know where the malta device is mapped in memory, which is quite convenient:
simics> break-io malta
- Check that we have a breakpoint by listing all breakpoints, with break-io -list:
simics> break-io -list breaking enabled for these devices: malta
- Enable logging by setting a log-size:
simics> log-size size = 10 Setting new size of all log buffers: 10
- See the debug tips page for more on I/O breakpoint and other Simics breakpoints. You can also read Chapter 8 of the User's Guide for UNIX (or Chapter 7 in the User's Guide for Windows) for more on Simics breakpoints.
- Start simulation with the continue command. Simics will stop at the first access to the malta device, showing you the type and values of the access. Note that the instruction displayed is the one after the accessing instruction, as the stop takes place after we execute the instruction.
simics> c [cpu0 -> malta] Write: 0x1f000418 4 0x4c [cpu0] v:0x802086b4 p:0x002086b4 j 0x802086c0
- This tells us that a value of "0x4c" (character code for "L") was written to address 0x1f000418, and that the size of the write was 4 bytes. This can be verified by looking at the access history of the malta device:
simics> malta.log 0 Timestamp: obj = malta cycle = 109011 cpu = cpu0 pc = 0x802086b0 Write access from cpu0. PA = 0x1f000418 size = 4 data = 0x4c Only 1 entries listed (no more in buffer)
- Note the information about the time of the access, who did it (which processor), and which instruction did the access. The accessing instruction was not the jump instruction at 0x802086b4, but the previous instruction at 0x80216a10. Also note that the address of the access is consistent with the memory map of the MIPS machine.
- To see the accessing instruction, use the da (disassemble) command:
simics> da 0x802086b0 v:0x802086b0 p:0x002086b0 sw v0,0(v1)
- Do c a few times to see the display of the word "LINUX" build up on the LCD. Each breakpoint will correspond to an additional letter being set.
- Look at the access history for malta again:
simics> malta.log 4 Timestamp: obj = malta cycle = 109047 cpu = cpu0 pc = 0x802086b0 Write access from cpu0. PA = 0x1f000438 size = 4 data = 0x58 3 Timestamp: obj = malta cycle = 109038 cpu = cpu0 pc = 0x802086b0 Write access from cpu0. PA = 0x1f000430 size = 4 data = 0x55 2 Timestamp: obj = malta cycle = 109029 cpu = cpu0 pc = 0x802086b0 Write access from cpu0. PA = 0x1f000428 size = 4 data = 0x4e 1 Timestamp: obj = malta cycle = 109020 cpu = cpu0 pc = 0x802086b0 Write access from cpu0. PA = 0x1f000420 size = 4 data = 0x49 0 Timestamp: obj = malta cycle = 109011 cpu = cpu0 pc = 0x802086b0 Write access from cpu0. PA = 0x1f000418 size = 4 data = 0x4c Only 5 entries listed (no more in buffer)
- That's enough with malta. Remove the breakpoint using the unbreak-io command, and check that it is gone:
simics> unbreak-io malta simics> break-io -list breaking enabled for these devices:
- The next step is to let the boot run until it displays "Linux" on the serial console (the regular text window, not the little LCD display). This is done using the con0.break command. We continue immediately to see the effect:
simics> con0.break "Linux" simics> c [text-console - con0] Breaking on string 'Linux' [text-console] Break on string [cpu0] v:0x801a3e04 p:0x001a3e04 addiu v0,zero,2
- The con0.break command stops as soon as the given string is displayed on the console. This is very handy when you want to script a program or an OS boot, for example to automatically log in each time the machine is started. Just add a sequence of commands at the end of a .simics file.
- We can also break when interrupts happen in the processor. We use the break-exception command, telling Simics to stop when the MIPS processor gets an interrupt (note that interrupts are just one of the types of exceptions that we can detect):
simics> break-exception Interrupt simics> c [cpu0] (@ cycle 104196745) Exception 0: Interrupt [cpu0] v:0x80000200 p:0x00000200 j 0x80208100
- The instruction shown is the one that will be executed as a result of the interrupt. To find the interrupt handler, we will need to single-step from here, using the si command (note that by pressing return in Simics, we simply reexecute the last command). The result looks like this, note that we jump from the interrupt vector into the interrupt handler (more on that below):
simics> si [cpu0] v:0x80000204 p:0x00000204 nop simics> [cpu0] v:0x80208100 p:0x00208100 mfc0 k0,12 sel = 0 (status) simics> da %pc 10 v:0x80208100 p:0x00208100 mfc0 k0,12 sel = 0 (status) v:0x80208104 p:0x00208104 nop v:0x80208108 p:0x00208108 sll k0,k0,3 v:0x8020810c p:0x0020810c bltz k0,0x8020811c v:0x80208110 p:0x00208110 move k1,sp v:0x80208114 p:0x00208114 lui k1,0x8025 v:0x80208118 p:0x00208118 lw k1,-23752(k1) v:0x8020811c p:0x0020811c move k0,sp v:0x80208120 p:0x00208120 addiu sp,k1,-176 v:0x80208124 p:0x00208124 sw k0,140(sp)
- Run until you hit the next interrupt. Then look at the contents of the cause register to determine the type of interrupt that hit us (look in the MIPS Processor Manual for the details on the cause register). Do cpu0.pregs -all to see all the CPU registers and their values (this is a really long output):
simics> c [cpu0] (@ cycle 104507910) Exception 0: Interrupt [cpu0] v:0x80000200 p:0x00000200 j 0x80208100 simics> cpu0.pregs -all zero [r0] = 0x00000000 s0 [r16] = 0x00000000 at [r1] = 0x80250000 s1 [r17] = 0x00000000 v0 [r2] = 0x00000008 s2 [r18] = 0x00000000 v1 [r3] = 0x00002000 s3 [r19] = 0x00000000 a0 [r4] = 0x00000008 s4 [r20] = 0x00000000 a1 [r5] = 0x00000001 s5 [r21] = 0x00000000 a2 [r6] = 0x00000001 s6 [r22] = 0x00000000 a3 [r7] = 0x00000007 s7 [r23] = 0x00000000 t0 [r8] = 0x80a5d930 t8 [r24] = 0x00000003 t1 [r9] = 0x0000003c t9 [r25] = 0x0000000a t2 [r10] = 0x00000018 k0 [r26] = 0x80107f98 t3 [r11] = 0xffffffe0 k1 [r27] = 0x80107f98 t4 [r12] = 0x80a5d546 gp [r28] = 0x80106000 t5 [r13] = 0xfffffffe sp [r29] = 0x80107f80 t6 [r14] = 0xffffffff fp [r30] = 0x00000000 t7 [r15] = 0x80107e91 ra [r31] = 0x80238388 HI 0x00000004 LO 0x00000000 PC 0x80000200 NPC 0x80000204 Coprocessor 0 registers: ------------------------ PRId 0x00018000 Config 0x80000083 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 M K K K K K K - - - - M - M M B B A A A A A M M M - - - - K K K 2 2 2 U U U D M M M E T T R R R T T T 0 0 0 3 3 3 2 1 0 U 1 0 2 1 0 2 1 0 2 1 0 Config1 0x9e180c02 1 0 0 1 1 1 1 0 0 0 0 1 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 - M M M M M M I I I I I I I I I D D D D D D D D D - - P W C E F M M M M M M S S S L L L A A A S S S L L L A A A C R A P P U U U U U U 2 1 0 2 1 0 2 1 0 2 1 0 2 1 0 2 1 0 Status 0x1000fc03 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 C C C C R - R - - B T S N - - - I I I I I I I I - - - U - E E I U U U U P E E S R M M M M M M M M M M R X E 3 2 1 0 V I 7 6 5 4 3 2 1 0 L L Cause 0x00808000 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 B - C C - - - - I W - - - - - - I I I I I I I I - E E E E E - - D E E V P P P P P P P P P X X X X X 1 0 7 6 5 4 3 2 1 0 C C C C C ...
- Single-stepping from an interrupt will bring us through the MIPS exception vectors (which contain code) into the actual interrupt handler. Note the purpose of the jump instruction at address 0x00000200 is simply to jump to real interrupt handler elsewhere in memory. The result is similar to this:
simics> si [cpu0] v:0x80000204 p:0x00000204 nop simics> si [cpu0] v:0x80208100 p:0x00208100 mfc0 k0,12 sel = 0 (status) simics> si [cpu0] v:0x80208104 p:0x00208104 nop
- To see what happens to the control registers of the MIPS during the exception handling, we can let Simics use its tracing facilities while the code is running. Try the trace-cr command to start tracing control register changes. Then run some number of instructions using the c command with an argument:
simics> trace-cr -all simics> c 1000 [cpu0] status <- 0x1000fc00 [cpu0] status <- 0x1000fc00 [cpu0] status <- 0x1000fc00 [cpu0] compare <- 0x1a3ad49 [cpu0] status <- 0x1000fc00 [cpu0] status <- 0x1000fc01 [cpu0] status <- 0x1000fc00 [cpu0] status <- 0x1000fc01 [cpu0] status <- 0x1000fc00 [cpu0] status <- 0x1000fc01 [cpu0] status <- 0x1000fc00 [cpu0] status <- 0x1000fc01 [cpu0] status <- 0x1000fc00 [cpu0] status <- 0x1000fc00 [cpu0] status <- 0x1000fc03 [cpu0] epc <- 0x802383b4 [cpu0] v:0x802383d0 p:0x002383d0 bne v1,zero,0x802383d0
- To stop tracing, use untrace-cr -all. Note that you can trace only a particular control register by giving its name to the trace-cr command.
- To stop when a control register changes, use break-cr with the name of a control register or -all, as with all other breakpoint commands (note that as always, your output might be different depending on when in the boot process you execute the Simics commands):
simics> break-cr -all simics> c [cpu0] (@ cycle 105007908) Exception 0: Interrupt [cpu0] v:0x80000200 p:0x00000200 j 0x80208100 simics> c [cpu0] status <- 0x1000fc00 [cpu0] v:0x802081e4 p:0x002081e4 mfc0 s0,13 sel = 0 (cause)
- That's it for showing off Simics features as an OS debugger.
Checkpointing
A very powerful feature of Simics is the ability to take a checkpoint of an execution and later continue from that same point. Basically, you write a snapshot of the system state to disk and bring it back into the machine, letting it continue from the point where you left off. We will demonstrate this using the Linux system.
- Start Simics running Linux as shown previously.
- Issue the command c 100_000_000, i.e. run one hundred million instructions.
- When Simics gets back to prompt, look at the state of the machine with commands:
- How does the text console look?
- The register contents: cpu0.pregs
- The execution stats to date: cpu0.print-statistics
- Now save a checkpoint using the command write-configuration:
simics> write-configuration example-checkpoint simics>
- Quit Simics.
- Next, look in the filesystem for the files generated by the checkpoint:
host$ ls compiler.mk modules config.mk simics example-checkpoint simics-eclipse example-checkpoint.ram_image student-setup.tar example-checkpoint.raw targets GNUmakefile v9-sol8-64
- Note all the files named example-checkpoint + something else: they are all part of the checkpoint.
- Now start Simics using the checkpoint, to get back to where we were. Use the -c argument to tell Simics to open the checkpoint:
host$ simics -c example-checkpoint
- Inspect the state of the machine using the same commands as above. Note that the statistics have been zeroed: when a checkpoint is taken, only persistent machine state is saved, and not the state of statistics gathering.
Hindsight
A new feature in Simics 3.0, Hindsight enables the simulation to run backwards in time.
- Restart Simics with the Linux machine, as before. Run with c, and press ctrl-C when the Linux command prompt appears.
simics> c [pci_to_usb0 spec-viol] 4 byte write access at offset 0xc0 in pci_config outside registers or misaligned access [cpu0] v:0x80108704 p:0x00108704 lui v0,0x8025
- Set a time bookmark, so that we later can go back in time...
simics> set-bookmark booted simics> c
- Now, in the Linux console write:
sh-2.04# rm /bin/ls sh-2.04# ls sh: ls: command not found sh-2.04#
- As you can see, we have remove the ls command. We will now use Hindsight to recover ls. Press ctrl-C and type ptime:
[cpu0] v:0x80108704 p:0x00108704 Pending interrupt simics> ptime processor steps cycles time [s] cpu0 3620993844 3620993844 72.420
- We now use skip-to to find a previous point in time. Note that it is not possible to reverse past the first bookmark.
simics> skip-to bookmark = booted [cpu0] v:0x80108704 p:0x00108704 lui v0,0x8025 simics> ptime processor steps cycles time [s] cpu0 1500602735 1500602735 30.012
- The system is now in the state it was before the file was erased. Run forward again:
simics> c
- Simics does not respond to input, but plays back the previous run. This is invaluable when debugging as it keeps the replay deterministic, but in this example we want to forget the future. Skip back again, and use the clear-recorder command:
simics> skip-to bookmark = booted [cpu0] v:0x80108704 p:0x00108704 lui v0,0x8025 simics> clear-recorder simics> c
- Resume the simulation and try ls:
sh-2.04# ls bin etc lib lost+found usr dev host linuxrc proc sh-2.04#
- ls works again!
Testing Simics with an example program
Next, let us try running a small example program on the compsys machine. There is a ready-compiled example timer program included in the installation of the compsys machine, called example_timer.elf which we will use here. This step will also check that your installation of compsys was correct and complete.
- Look at the script mips-simple-common.simics in targets/mips-simple. This is the script used to start simics. It is quite short; basically all that is done is to set a variable and then hand over to the mips-simple-*.include scripts that does the machine setup.
- Start Simics using this script (we ignore most of the Simics output in the example below):
host$ ./simics targets/mips-simple/mips-simple-common.simics Simics started Binary loaded: example_timer.elf Start address: 80020400 simics>
- Start simulating using c. Note that we loaded this program into the memory of the machine without any operating system being part of the process; we are running it directly on the hardware, just like you will with your own operating systems.
- Stop the program and experiment with the debugging features of Simics. Which devices and interrupts does the program use?
- Note that you will be using some convenient scripts to run your own programs in Simics, as described in the compilation introduction lab.
Scripting Simics
Optionally, you might want to investigate the possibilities of extending the Simics command line using scripting. As example here, we will add a command that stops execution as soon as an eret instruction is found.
To start, we will set a breakpoint on eret instructions using the command line interactively. This process relies on a breakpoint filtering feature in Simics (to find more information on the commands, do help break and help set-prefix).
- Set a breakpoint on the entire memory containing instructions (in virtual addresses for the Linux example, the memory is much smaller for the compsys machine):
simics> break -x 0x8000_0000 0x0800_0000 Breakpoint 1 set on address 0x80000000, length 134217728 with access mode 'x'
- If you try executing, you will stop on every instruction. Which is not very practical.
- We can modify this breakpoint to match just specific instructions. This is done using one of the commands
set-prefix, set-substr, or set-pattern. For the eret instuction, prefix is the most appropriate. Note that we need to specify the ID number of the breakpoint to modify:
simics> set-prefix 1 "eret" simics> list-breakpoints Id Type Enb Start Stop Hits Space 1 virt-x yes 0x0000000080000000 0x0000000087ffffff 0 primary_context Prefix: eret
- Let the simulation run. After a while, it should stop when it finds an eret instruction:
simics> c Code breakpoint 1 reached. [cpu] v:0x800205a0 p:0x000205a0 eret
- This is quite a lot of typing to do each time such a breakpoint is desired. Instead, we can create a small script-file that does the job for us. Open up an emacs or other text editor, and enter the commands used above on consecutive lines:
break -x 0x80000000 0x08000000 set-prefix 1 "eret"
- Save this under a name (like "setbp.simics") in the Simics directory you are currently using (likely targets/malta or targets/mips-simple).
- Quit Simics and restart it, so you have a new fresh machine.
- Load the command-file you saved using the command run-command-file:
simics> run-command-file setbp.simics
- Check that the breakpoint triggers as before when your program executes.
As you might see, the above solution only works for a single breakpoint, since we have hardcoded the breakpoint ID number in the argument to the set-prefix command. The only way to fix this limitation is to move to Python scripting and use the Simics API (as described in the Simics User's Guide. Feel free to explore this aspect of Simics on your own.
Anyway, putting common command sequences into script files is handy for repeating tasks with Simics, or to automate testing. When doing the labs, the run.simics file and the run.sh script will be used. These files can be extended with new commands during project development.