First of all, I cannot use a debugger[1]. But I can access the Program Counter of a program, and can also compile the binary (written in C) with all the flags I need. And I can even change the code (although I prefer not to). Given a PC I want to be able to know which line it corresponds.
I'm sure there has to be an automated, practical, quick way to do this. But I haven't succeeded.
Edit: Forgot to mention: Linux system, binaries are PPC, host is i386. I do have access to PPC hardware.
[1] The application is being emulated, and it is cross compiled, I have a gdb in the host emulator. But I cannot connect a gdbserver on the emulated guest application. And real hardware is not an option, I'm trying to build a simulator based on the emulator.
If the binary is compiled with debugging information, then you can use the PC to find the right location in the source by groping through the ELF sections that contain the debug information. Automated, quick and practical aren't the terms that spring to mind for the process, though!
Related
OK, so I am trying to connect an emulated (Through TSIM) LEON3 processor to a UART terminal. If I am not mistaken I believe I need to compile a C program to enable it to talk with a terminal as I am having difficulties doing it another way.
I found some source code for UART communication here and it all seems to be OK.
However, I am having issues compiling it using the SPARC Bare C Toolchain in Eclipse as it is saying that the windows.h file does not exist. Now I know it exists as I've compiled it successfully using the GCC Toolchain and can't find any similar cases on the web as to why this would be happening.
Is there anyone out there who has had a similar problem or knows the solution?
Additionally, if you know me to be doing the wrong thing in regards to the LEON3 UART comms, please let me know and I will just leave.
Thanks.
BCC is a cross compiler targeting standalone, LEON3- and LEON4-based environments. As a cross compiler, its job is to build binaries for a different environment than the one in which it runs.
Relevant header files describe functions available to a program in its runtime (target) environment. Build-environment libraries and their headers are irrelevant when cross compiling because the build and target environments differ. BCC is correct to expose only the headers for the environment for which it compiles, and that environment does not provide Windows API functions. If the code you're trying to build depends on the Windows API, then you'll need to modify it to remove that dependency, or else find something different.
On the other hand, I strongly suspect that you're going about this whole thing the wrong way. In particular, when you say,
I believe I need to compile a C program to enable it to talk with a terminal
it sounds like you think you're going to build some kind of helper program, but if that's your idea then either you're building it for the wrong environment or you have the wrong idea altogether.
If you want a Windows program that talks to the emulated machine, then you should be building that as a Windows program, and BCC doesn't do that. In that case, you should be using MinGW's gcc, or another C compiler for the emulator's host environment. Moreover, the host-side interface to the emulated environment's UART is an aspect of the emulator. I haven't a clue what emulator you're using, but it might not present the host (Windows) side of that interface as a UART, and it might not require using the Windows API at all.
Or if you indeed do intend to build a program for the standalone LEON3 target environment, then you need to understand that when it runs, it will be the only program that will be running in that environment. That's what "standalone" means -- no OS underneath, therefore no separate processes, and often not even multiple threads of execution. Thus, you do not need a helper program; you just need a program.
The BCC documentation talks about the libraries available there, and in particular, it describes how in that environment, file I/O is allowed only on the standard input and output streams, which are mapped to UART A. Thus, if you use BCC to build the program to run in the emulator, then you don't need to do anything special on that end to talk to the UART. You just use stdio functions directed at stdin and stdout.
On the third hand, if you are running an actual operating system in your emulated environment, then to build programs that run on it you should be using either a native compiler for that environment, in that environment, or else a cross compiler targeting that hosted environment. Either way, BCC is not such a compiler, but GCC might be. Anyway, since Windows does not run on LEON3, it's safe to say that if this is what you're trying to do then you still need something that does not depend on the Windows API.
I have cross-compiled a kernel, in an autodidactic manner, on a raspberry pi twice in the past.
This kind of things can sometimes a pain in the ... But fortunately there are some step-by-step tutorials.
So I am wondering whether there are general steps that have to be taken and that are the same on all the embedded systems (rpi, beaglebone, atmega controllers, etc...) in order to successfully cross-compile the kernel and make everything work?
My guess:
1) download the kernel source code
2) generate a .config file (which seems necessary)
3) get into the blue screen to do additional adjustements
with e.g.: make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi- menuconfig
4) compile the kernel:
make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnueabi-
5) put it on the SD card or anything else
Would this be a correct general scheme for any cross-compilation on an embedded system?
Sorry for my ignorance, as I mentioned above I learned it by myself.
I would like to be able to setup a kernel on any embedded device.
Any more information or explanation would be more than welcome! As it seems this kind of things can always be done in multiple manners, it gets me confused.
I'd say your first two steps haven't much to do with cross-compiling. In fact it just comes down to having a cross toolchain targeting your platform correctly installed on your system.
The CROSS_COMPILE make variable of the kernel doesn't do anything other than prepending the string it is set to to any toolchain command (like e.g. gcc for compiling), so if your cross toolchain is installed in your search path, it would be enough to set it to just the desired target triplet with added hyphen, e.g. in your case CROSS_COMPILE=arm-linux-gnueabi-. This would lead to using the command arm-linux-gnueabi-gcc for compiling and so on.
For other embedded devices, you might need different cross toolchains (depending on their architecture), but the general process would indeed stay the same.
I was wondering if anyone knows an efficient way to program the FPGA(PL) for a Xilinx Zynq-7 series or related devices,from a host C program (not on the SoC, but from the host PC). Is there an Xilinx API I can use/include in my program. As the only way I can think of doing it at the moment is invoking command line programming via Impact.
Basically I want to put the SDK "Program FPGA" functionality in my host C program where the user selects a prebuilt .bit file (and .elf file if possible) to program the FPGA/(SoC). This is just for a test of concept, later I would like to put this dynamic configuration onto one of the ARM CPU's.
Many Thanks
Sam
At the very least you'll need an intermediate MPU/MCU that can read from USB, as at startup most FPGAs aren't capable of much at all. I'm guessing this'll make it hard to find a MPU/library pair to do so, because there are so many options, each of which would be pretty application-specific. You're better off starting with programming them off an ARM chip, since you'll need some CPU with the FPGA in any case.
This seems somewhat useful.
I have such setup. I need to program on some embedded device which in spec says to run Linux (although when you turn on the device, clearly the display doesn't show anything linux related - small display).
The embedded device has its own SDK.
Now, I thought using valgrind to check for memory management/allocation.
Can I use valgrind to check a program written for my device?
The problem I see is that the program might contain some device specific SDK calls, hence the program might not run on ordinary fedora linux that I run on my desktop for example.
What are my options?
Running valgrind on embedded devices can be quite challenging, if not impossible.
What you can do is to create unit tests, and execute them using valgrind on the host platform. That is a way to at least check memory problems of part of the code.
Other option is to use platform emulation, and run programs in emulators (again on the host system). QEMU is quite famous open source emulator.
Perhaps.
Make sure you really run Linux, of course.
Figure out the hardware platform; Valgrind supports quite a few platforms but not all.
Consider whether your platform has resources (memory and CPU speed) to spare; running Valgrind is quite costly.
If all of those check out ok, then you should be able to run Valgrind, assuming of course you can get it onto the target machine. You might need to build and install it yourself, of course.
I assume you have some form of terminal/console access, i.e. over serial port, telnet, or something that you can use to run programs on the target.
UPDATE: Based on feedback in comments, I'm starting to doubt the possibility for you to run Valgrind on your particular device.
I don't quite understand the compiling process of the Linux kernel when I install
a Linux system on my machine.
Here are some things that confused me:
The kernel is written in C, however how did the kernel get compiled without a compiler installed?
If the C compiler is installed on my machine before the kernel is compiled, how can the compiler itself get compiled without a compiler installed?
I was so confused for a couple of days, thanks for the response.
The first round of binaries for your Linux box were built on some other Linux box (probably).
The binaries for the first Linux system were built on some other platform.
The binaries for that computer can trace their root back to an original system that was built on yet another platform.
...
Push this far enough, and you find compilers built with more primitive tools, which were in turn built on machines other than their host.
...
Keep pushing and you find computers built so that their instructions could be entered by setting switches on the front panel of the machine.
Very cool stuff.
The rule is "build the tools to build the tools to build the tools...". Very much like the tools which run our physical environment. Also known as "pulling yourself up by the bootstraps".
I think you should distinguish between:
compile, v: To use a compiler to process source code and produce executable code [1].
and
install, v: To connect, set up or prepare something for use [2].
Compilation produces binary executables from source code. Installation merely puts those binary executables in the right place to run them later. So, installation and use do not require compilation if the binaries are available. Think about ”compile” and “install” like about “cook” and “serve”, correspondingly.
Now, your questions:
The kernel is written in C, however how did the kernel get compiled without a compiler installed?
The kernel cannot be compiled without a compiler, but it can be installed from a compiled binary.
Usually, when you install an operating system, you install an pre-compiled kernel (binary executable). It was compiled by someone else. And only if you want to compile the kernel yourself, you need the source and the compiler, and all the other tools.
Even in ”source-based” distributions like gentoo you start from running a compiled binary.
So, you can live your entire life without compiling kernels, because you have them compiled by someone else.
If the C compiler is installed on my machine before the kernel is compiled, how can the compiler itself get compiled without a compiler installed?
The compiler cannot be run if there is no kernel (OS). So one has to install a compiled kernel to run the compiler, but does not need to compile the kernel himself.
Again, the most common practice is to install compiled binaries of the compiler, and use them to compile anything else (including the compiler itself and the kernel).
Now, chicken and egg problem. The first binary is compiled by someone else... See an excellent answer by dmckee.
The term describing this phenomenon is bootstrapping, it's an interesting concept to read up on. If you think about embedded development, it becomes clear that a lot of devices, say alarm clocks, microwaves, remote controls, that require software aren't powerful enough to compile their own software. In fact, these sorts of devices typically don't have enough resources to run anything remotely as complicated as a compiler.
Their software is developed on a desktop machine and then copied once it's been compiled.
If this sort of thing interests you, an article that comes to mind off the top of my head is: Reflections on Trusting Trust (pdf), it's a classic and a fun read.
The kernel doesn't compile itself -- it's compiled by a C compiler in userspace. In most CPU architectures, the CPU has a number of bits in special registers that represent what privileges the code currently running has. In x86, these are the current privilege level bits (CPL) in the code segment (CS) register. If the CPL bits are 00, the code is said to be running in security ring 0, also known as kernel mode. If the CPL bits are 11, the code is said to be running in security ring 3, also known as user mode. The other two combinations, 01 and 10 (security rings 1 and 2 respectively) are seldom used.
The rules about what code can and can't do in user mode versus kernel mode are rather complicated, but suffice to say, user mode has severely reduced privileges.
Now, when people talk about the kernel of an operating system, they're referring to the portions of the OS's code that get to run in kernel mode with elevated privileges. Generally, the kernel authors try to keep the kernel as small as possible for security reasons, so that code which doesn't need extra privileges doesn't have them.
The C compiler is one example of such a program -- it doesn't need the extra privileges offered by kernel mode, so it runs in user mode, like most other programs.
In the case of Linux, the kernel consists of two parts: the source code of the kernel, and the compiled executable of the kernel. Any machine with a C compiler can compile the kernel from the source code into the binary image. The question, then, is what to do with that binary image.
When you install Linux on a new system, you're installing a precompiled binary image, usually from either physical media (such as a CD DVD) or from the network. The BIOS will load the (binary image of the) kernel's bootloader from the media or network, and then the bootloader will install the (binary image of the) kernel onto your hard disk. Then, when you reboot, the BIOS loads the kernel's bootloader from your hard disk, and the bootloader loads the kernel into memory, and you're off and running.
If you want to recompile your own kernel, that's a little trickier, but it can be done.
Which one was there first? the chicken or the egg?
Eggs have been around since the time of the dinosaurs..
..some confuse everything by saying chickens are actually descendants of the great beasts.. long story short: The technology (Egg) was existent prior to the Current product (Chicken)
You need a kernel to build a kernel, i.e. you build one with the other.
The first kernel can be anything you want (preferably something sensible that can create your desired end product ^__^)
This tutorial from Bran's Kernel Development teaches you to develop and build a smallish kernel which you can then test with a Virtual Machine of your choice.
Meaning: you write and compile a kernel someplace, and read it on an empty (no OS) virtual machine.
What happens with those Linux installs follows the same idea with added complexity.
It's not turtles all the way down. Just like you say, you can't compile an operating system that has never been compiled before on a system that's running that operating system. Similarly, at least the very first build of a compiler must be done on another compiler (and usually some subsequent builds too, if that first build turns out not to be able to compile its own source code just yet).
I think the very first Linux kernels were compiled on a Minix box, though I'm not certain about that. GCC was available at the time. One of the very early goals of many operating systems is to run a compiler well enough to compile their own source code. Going further, the first compiler was almost certainly written in assembly language. The first assemblers were written by those poor folks who had to write in raw machine code.
You may want to check out the Linux From Scratch project. You actually build two systems in the book: a "temporary system" that is built on a system you didn't build yourself, and then the "LFS system" that is built on your temporary system. The way the book is currently written, you actually build the temporary system on another Linux box, but in theory you could adapt it to build the temporary system on a completely different OS.
If I am understanding your question correctly. The kernel isn't "compiling itself" these days. Most Linux distributions today provide system installation through a linux live cd. The kernel is loaded from the CD into memory and operates as it would normally as if it were installed to disk. With a linux environment up and running on your system it is easy to just commit the necessary files to your disk.
If you were talking about the bootstrapping issue; dmckee summed it up pretty nice.
Just offering another possibility...