I am working on a simple OS for arm using qemu and uboot. I can load uboot fine and can load the image with using the 'bootm' command followed by the corresponding address. I want the kernel image to load automatically without having to call bootm. I added "#define CONFIG_BOOTCOMMAND "bootm 0x28124"" to the versatile.h file and it loads automatically, but the issue is that this address can change. I am using versatilepb and I thought it was strange that uboot is missing a lot of the commands that the documentations says it should have.
u-boot copy compressed kernel image onto memory and then jump to this kernel image's entry point. Then the kernel decompress and put kernel onto proper location at memory.
As the offset of kernel entry to kernel image is fixed, and the location of compressed kernel is determined by u-boot and usually fixed.
You wont need to change your bootm address when kernel size changes
Related
I'm using libtcmalloc.so with LD_PRELOAD on some executable and it works fine. The problem is, that the output only contains the difference compared to the previous file. But I would like to see all allocated memory (and not freed) since the start of the process.
I meet this problem when finishing the lab of my OS course. We are trying to implement a kernel with the function of system call (platform: QEMU/i386).
When testing the kernel, problem occurred that after kernel load user program to memory and change the CPU state from kernel mode to user mode using 'iret' instruction, CPU works in a strange way as following.
%EIP register increased by 2 each time no matter how long the current instrution is.
no instruction seems to be execute, for no other registers change meantime.
Your guest has probably ended up executing a block of zeroed out memory. In i386, zeroed memory disassembles to a succession of "add BYTE PTR [rax],al" instructions, each of which is two bytes long (0x00 0x00), and if rax happens to point to memory which reads as zeroes, this will effectively be a 2-byte-insn no-op, which corresponds to what you are seeing. This might happen because you set up the iret incorrectly and it isn't returning to the address you expected, or because you've got the MMU setup wrong and the userspace program isn't in the memory where you expect it to be, for instance.
You could confirm this theory using QEMU's debug options (eg -d in_asm,cpu,exec,int,unimp,guest_errors -D qemu.log will log a lot of execution information to a file), which should (among a lot of other data) show you what instructions it is actually executing.
As all information I found about Qemu is related to Linux kernel, uboot or elf binaries I can't quite figure out how to load a binary blob from an embedded device into a specific address and execute part of it. The code I want to run does only arithmetics, so there are no hardware dependencies involved.
I would start qemu with something like
qemu-arm -singlestep -g8000
attach gdb, set initial register state and jump to my starting address to single step through it.
But how do I initially load binary data to a specific address and eventually set up an additional ram range?
how to load a binary blob from an embedded device into a specific address and execute part of it.
You can load binary blob into softmmu QEMU by the generic loader (-device loader).
I would start qemu with something like
qemu-arm -singlestep -g8000
This command line is for the linux-user QEMU invocation. It emulates userspace linux process of the guest architecture, it is unprivileged and does not provide support for any devices, including generic loader. Try using qemu-system-arm instead.
It's in fact easy with the Unicorn framework which works on top of Qemu. Based on the example in the websites doc section I wrote a Python script which loads the data, sets the registers, adds a hook which prints important per step information and start execution at the desired address until a target address.
I have a question :
Let's say I have 2 GPU:s in my system and I have 2 host processes running cuda code. How can I be sure that each takes a GPU?
I'm considering setting exclusive_thread but I cannot understand how to get advantage of it: once I check that a device is free how can I be sure that it remains free until I do a cudaSetDevice?
EDIT:
So far I've tried this:
int devN = 0;
while (cudaSuccess != cudaSetDevice(devN))devN = (devN + 1) % 2;
but I get a
CUDA Runtime API error 77: an illegal memory access was encountered.
which is not strange since I am in EXCLUSIVE_PROCESS mode.
Two elements within this question. Assigning a process to a GPU and making sure a GPU is available for a single process.
Assigning a process to a GPU
There is a simple way to accomplish this using CUDA_VISIBLE_DEVICES environment variable: start you first process with CUDA_VISIBLE_DEVICES=0 and your second process with CUDA_VISIBLE_DEVICES=1. Each process will see a single GPU, with device index 0, and will see a different GPU.
Running nvidia-smi topo -m will display GPU topology and provide you with the corresponding CPU affinity.
Then, you may set CPU affinity for your process with taskset or numactl on linux or SetProcessAffinityMask on Windows.
Process has exclusive access to a GPU
To make sure that no other process may access your GPU, configure the GPU driver to be in exclusive process: nvidia-smi --compute-mode=1.
How do you write to the processor registers and specific memory addresses of a virtual system running in QEMU?
My desire would be to accomplish this from a user space program running outside of QEMU. This would be to induce interrupts and finely control execution of the processor and virtual hardware.
The QEMU Monitor is supposed to read parameters or do simple injects of mouse or keyboard events, but I haven't seen anything about writing.
GDB server within QEMU Monitor seems to be the best for your purpose. One of your options is implementing a gdb protocol, another one is driving gdb itself through its command line.
I've tested it a bit: attaching, reading and writing memory seems to work (I read what I write); jumping to another address seems to work too. (If you may call injected code, you can do anything, theoretically). Writing to text-mode video memory doesn't work (I don't even read what I wrote, and nothing changes on display).