I've been carefully following this tutorial : https://www.barebox.org/doc/latest/boards/stm32mp.html to flash Barebox on a STM32 MCU but I'm stuck at the "Building barebox" step.
When I type make ARCH=arm stm32mp_defconfig I see the makefile executes without any error. Here are the logs :
HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
HOSTCC scripts/kconfig/confdata.o
HOSTCC scripts/kconfig/expr.o
LEX scripts/kconfig/lexer.lex.c
YACC scripts/kconfig/parser.tab.[ch]
HOSTCC scripts/kconfig/lexer.lex.o
HOSTCC scripts/kconfig/menu.o
HOSTCC scripts/kconfig/parser.tab.o
HOSTCC scripts/kconfig/preprocess.o
HOSTCC scripts/kconfig/symbol.o
HOSTCC scripts/kconfig/util.o
HOSTLD scripts/kconfig/conf
#
# configuration written to .config
#
but at the end I don't have any image in the images/ folder.
I tried to proceed in the tutorial but I clearly see in the next step that I need .img files in the images/ folder...
I feel totally lost since I followed the tutorial very carefully and nothing indicates me when I could have done an error...
Otherwise, if someone knows a more simple way to flash Barebox in a STM32 MCU hmu. I've already spent hours on this and this tutorial makes me feel lost af.
barebox uses Kbuild, the Linux kernel build system. make ARCH=arm stm32mp_defconfig will configure barebox appropriately for the STM32MP by creating a new .config file with all the settings. Afterwards you need to just call make to actually build this configuration:
make ARCH=arm
And then you will have the images built. This is described in detail in the barebox documentation. The board documentation you looked at is like a quick start which assumes familiarity with the main documentation, but I have nevertheless just sent a patch amending it.
With this one extra `make call, you should now have images for a couple of STM32MP boards, but these are application processors (with MMU, no built-in flash, some with GPU, ... etc.) and not microcontrollers. There is no mainline support for STM32 MCUs. I have hacked together some support for the STM32F429I-DISCO, but I have yet to upstream it. What board do you want to run barebox on?
Related
I've been spending the last week trying to reach one objective that i still haven't reached.
My final goal would be to cross-compile for some architectures (in this question i will take as an example only one which is MIPSLE) a couple of kernel modules that i'd like to use on my home router, by loading them at runtime with INSMOD.
My router is missing of some iptables functionalities and that's why during the kernel compilation, who compiled it decided to get rid of them.
The current kernel version is quite obsolete: Linux version 2.6.36+ by doing /proc/version
I read a lot of documentations and still i'm not sure if it possible to compile just some modules or if it's necessary to compile the whole kernel everytime (some people said that for some modules is possible and for others with more dependencies is not, is that true ?).
In this case the kernel modules i need are located in /net/ipv4/netfilter/
Since i didn't get how to compile just kernel modules in a standalone way, i decided to cross-compile the entire kernel and take the modules i needed.
So i've downloaded the proper toolchain (uclibc mipsle toolchain) and i was successfull in compiling a simple working hello world that i've executed on my router where i have an ssh shell.
So i'm sure that the toolchain i'm using it's the correct one.
Now, since i wanted to test with a recent version of kernel i've downloaded the latest ubuntu 20 with correspective kernel and i've successfully compiled it and the kernel modules that i was speaking about before, were there inside the netfilter folder in .ko format , PERFECT !
I clearly used the /boot/config_file of my host machine as .config
So, after I've downloaded the exact same kernel version that my router has (2.6.36) and I've tried to compile it with a .config file that i've found on GitHub related to a mipsle device with my same kernel version.
Here i think we have the first problem, I tried to find the .config of my device in order to have a smooth configuration but i don't have the /boot folder and in also was not in /proc.
How can i get it?
Anyway, I've used it and the compilation didn't look like failed, but these are the last lines:
CC drivers/usb/storage/usual-tables.o
LD drivers/usb/storage/usb-storage.o
LD drivers/usb/storage/built-in.o
LD drivers/usb/built-in.o
LD drivers/video/built-in.o
LD drivers/built-in.o
LD vmlinux.o
MODPOST vmlinux.o
GEN .version
CHK include/generated/compile.h
UPD include/generated/compile.h
CC init/version.o
LD init/built-in.o
LD .tmp_vmlinux1
KSYM .tmp_kallsyms1.S
AS .tmp_kallsyms1.o
LD .tmp_vmlinux2
KSYM .tmp_kallsyms2.S
AS .tmp_kallsyms2.o
LD vmlinux
SYSMAP System.map
SYSMAP .tmp_System.map
OBJCOPY arch/mips/boot/vmlinux.bin
Building modules, stage 2.
MODPOST 1 modules
CC drivers/scsi/scsi_wait_scan.mod.o
LD [M] drivers/scsi/scsi_wait_scan.ko
It says "1 Modules" but I don't understand why and inside the /net/ipv4/netfilter folder now I have .o files instead of .ko like if they've not been linked.
Since i was getting mad and I didn't know what to try more after several attempts, I've decided to use the config file of my host machine (ubuntu 2020, kernel 5.4.0.26) and the compilation was successful, with .ko files inside the folder.
The problem was that obviously they were modules compiled for x86-64 instead of MIPS and other clear "problems" related to the configuration of my x86-64 machine.
So, what i think now is that the .config I've found could be broken somehow, I also tried to disable, by adding a comment, that SCSI module, but nothing, I always get the same stuff.
And obviously between each try I always did a make distclean and make clean.
What do you suggest me to do? I won't even post all the references i've read about this stuff because i could sigsegv StackOverflow's server with that amount of data.
Thanks to everyone and sorry for the wall-post.
i'm not sure if it possible to compile just some modules or if it's necessary to compile the whole kernel every time
Well, you can compile just single modules, but compiling a module requires the kernel to be already built. Once you do that one time though, you should be able to compile other modules singularly. That is, of course, if you do not wish to embed them in the kernel itself (CONFIG_XXX=y instead of CONFIG_XXX=m). You should be able to compile only the module you want like this (assuming /path/to/linux is the directory where your already built kernel source resides):
$ cd /path/to/linux
$ cd path/to/module/folder
$ make -C /path/to/linux M=$(pwd) modules
I tried to find the .config of my device in order to have a smooth configuration but i don't have the /boot folder and it also was not in /proc. How can i get it?
Where did you look precisely? The presence of /proc/config.gz depends on CONFIG_IKCONFIG_PROC (see also here). If you cannot find the file then it's most likely because that configuration option was disabled when the kernel was built. You may try look under /boot (as you already did), or under /lib/modules/$(uname -r)/build/.config, but unfortunately there's not much else to do otherwise.
I've seen people suggest trying to run modprobe configs and then check /proc/config.gz, but that seems strange since as far as I know the kernel config shouldn't be configurable to be available as a loadable module.
What do you suggest me to do?
Well, the most important thing you want right now is to find the configuration file for your router (or a compatible one). If you cannot find that, it will be pretty hard to get everything right. You might want to search for OpenWRT versions available for your router (if any), or really anywhere else on the internet as long as you can find a suitable configuration. Include your router brand and/or model in your searches. StackOverflow can't really help you that much about this though.
You can try cross-compiling a 5.4 kernel with default config plus the module you want. For example, assuming you have the right cross-compilation toolchain ready:
cd /path/to/linux
make ARCH=mips CROSS_COMPILE=your-cross-toolchain-prefix- defconfig
make ARCH=mips CROSS_COMPILE=your-cross-toolchain-prefix- menuconfig
# ... enable the module, tune the config ...
make -j ARCH=mips CROSS_COMPILE=your-cross-toolchain-prefix-
In any case, consider the fact that jumping from a 2.6 to a 5.4 kernel is a pretty big change, and it's likely to end up breaking everything, so be sure to make a backup of your router's firmware before trying anything.
I have a Makefile made by following this example:
cross compile kernel module
I built a 4.14 Linux kernel from an older Xilinx source, and then built a out-of-kernel module with that script, pointing it to the said 4.14 kernel sources, and filling in the blanks for my particular platform architecture.
That worked.
(It's based on this code, if that matters: dma-proxy.c)
Now I need a newer version, and got Xilinx sources with a kernel named 5.6.0-rc1.
(--branch "zynqmp-soc-for-v5.7" from here)
Building that kernel also worked fine.
If I now use a scrubbed clean directory (incl. hidden files) with my module source code and that Makefile again, pointing to the newer kernel sources, it does neither produce a .ko file nor an error message.
All I get is:
make ARCH=arm64 CROSS_COMPILE="aarch64-linux-gnu-" -C /home/sk/src/XILINX/linux-xlnx SUBDIRS=/home/sk/src/XILINX/dma-proxy/driver modules
make[1]: Entering directory '/home/sk/src/XILINX/linux-xlnx'
CALL scripts/checksyscalls.sh
CALL scripts/atomic/check-atomics.sh
MODPOST 28 modules
make[1]: Leaving directory '/home/sk/src/XILINX/linux-xlnx'
No .ko file in my folder as it was before when building with 4.14, and it doesn't list actually compiling anything.
I find it curious that it says "MODPOST 28 modules", whereas with pointing it to kernel 4.14, it expectedly says "1 modules"
Has anything changed between 4.14 and 5.x that would cause this?
Mkay, here is the suggested makefile template by the tutorial I referenced in the question:
PWD := $(shell pwd)
obj-m += hello.o
all:
make ARCH=arm CROSS_COMPILE=$(CROSS) -C $(KERNEL) SUBDIRS=$(PWD) modules
clean:
make -C $(KERNEL) SUBDIRS=$(PWD) clean
Turns out that if I replace SUBDIRS=$(PWD) with M=$(PWD), it works. Now if I google explicitly for that M variable in conjunction with building kernel modules, I do find text that show it that way. But the net is also littered with examples using SUBDIRS, and it worked for me with a fairly recent kernel (4.14).
Then I did find references hinting at this being an old way of doing it, like from here:
make -C $KDIR SUBDIRS=$PWD
Same as M=. The SUBDIRS= syntax is kept for backwards compatibility.
In fact, this seems to be really old, like, kernel 2.6.7 old. Unfortunately, fairly recent tutorials show the old way.
I have some source files that previously have been compiled for X86 architecture. Now I need to compile them for ARM architecture. When I try to use something like
g++ -c -x c++ foo.h
gcc -c -x c foo.h
it only gives me few instructions. I believe it doesn't link my header file to other included files. I only get "Disassembly of section .comment:".
Please note it does prompt me for other files, for example if foo includes foo1.h and foo2.h, if I don't include foo1 and foo2 headers in the same directory the compiler doesn't work.
Another thing which I don't understand is that both gcc and g++ produce the same assembly code, maybe because they only generate the comment section they look the same.
A little bit more details about my problem:
I'm using a USB-I2C converter board. The board provides only support for x86/x64 architecture. I managed to access the source file and to get the driver setup. Now I need to test everything together. In order to do so I need to be able to compile a sample code. When I want to do so, it calls on static libraries that need to be in .a extension. I need to create my own library.a file. In order to do so, I have found the source c files (.h header). Now I need to link them together during compilation and make object files, and eventually archive them together in a .a file.
Thank you for your help.
Edit (update):
A quick summary of what I have achieved so far:
- I was able to find a driver from a github repo.
- I was able to make the module
- I also compiled a new fresh kernel from a raspbian source code (I'm doing this for a Raspberry PI3):
uname -a
Linux raspberrypi 4.9.35-v7+ #1 SMP Tue Jul 4 22:40:25 BST 2017 armv7l GNU/Linux
I was able to load the module properly:
lsmod
Module Size Used by
spi_diolan_u2c 3247 0
i2c_diolan_u2c 3373 0
diolan_u2c_core 4268 2 i2c_diolan_u2c,spi_diolan_u2c
lsusb
Bus 001 Device 010: ID a257:2014
dmesg
[ 126.758990] i2c_diolan_u2c: loading out-of-tree module taints kernel.
[ 126.759241] i2c_diolan_u2c: Unknown symbol diolan_u2c_transfer (err 0)
[ 130.651475] i2c_diolan_u2c: Unknown symbol diolan_u2c_transfer (err 0)
[ 154.671532] usbcore: registered new interface driver diolan-u2c-core
[ 5915.799739] usb 1-1.2: USB disconnect, device number 4
[10591.295014] usb 1-1.2: new full-speed USB device number 6 using dwc_otg
[10591.425984] usb 1-1.2: New USB device found, idVendor=a257, idProduct=2014
[10591.425997] usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[10591.426005] usb 1-1.2: Product: Diolan DLN1
[10591.426012] usb 1-1.2: Manufacturer: Diolan
What I'm not sure:
If the kernel space is properly mapped to physical hardware (if the loaded module can get ahold of my diolan-board)!!!
progress: based on my research, I think a hot-plug protocol would take care of that, but not sure!
confusion: why the lsusb still only shows the device ID. I know the manufacturer and kernel driver can determine what info to be shown, but only showing ID doesn't seem right to me
What I want to do now:
I would like to write a simple c source or python code to interact with my device. Basically I don't know how I can make connection between user space and kernel space. The manufacturer has provided some source code examples, libraries, etc. . However, I have given up on using them because they are for another architecture , based on qt, and I find it near impossible to find replacement for libraries they use in their static libraries ( I figured those libraries by restoring their .a archived file provided for x86)
I just need to know exactly what the next step should be for me to move on towards getting the board working with the PI.
Thank you :)
You don't make any object file from a header file. On Linux object files (and executables) are ELF files. Use file(1) (or objdump(1) ...) to check.
Instead, a header file should be included (by #include preprocessor directive) in some *.cc file (technically a translation unit).
(You could precompile headers, but this is only useful to improve compilation time, which it does not always, and is an advanced and GCC specific usage; see this)
You do compile a C++ source file (some *.cc file) into an object file suffixed .o (or a C source file *.c compiled into an object file suffixed .o)
Read more about the preprocessor, and do spend several days reading about C or C++ (which are different programming languages). Read also more about compiling and linking.
I recommend to compile your C++ code with g++ -Wall -Wextra -g to get all warnings (with -Wall -Wextra ) and debug information (with -g).
A minimal compilation command to compile some yourfile.cc in C++ into an object file yourfile.o should probably be
g++ -c -Wall -Wextra -g yourfile.cc
(you could remove -Wall -Wextra -g but I strongly recommend to keep them)
You may need to add other arguments to g++. They order matters a lot. Read the chapter about Invoking GCC
Notice that yourfile.cc contains very likely some (and often several) #include directives (usually near its start)
You very rarely need the -x c++ option to g++ (or -x c with gcc). I used it only once in my lifetime. In your case it surely is a mistake.
Very often, you use some build automation tool like GNU make. So you just use make to compile (but you need to write a Makefile - where tabs are significant)
Notice that some libraries can be header only (but this is not very usual), then you don't build any shared or static ELF libraries from them, but you just include headers in your own C or C++ code.
addenda
Regarding your http://dlnware.com/sites/dlnware.com/files/downloads/linux_setup.2.0.0.zip package (which indeed is poorly documented), you should look at the several examples given in the linux_setup/examples/ directory. Such code all have a #include "../common/dln_generic.h" (for instance, 4th line of examples/leds_gui/main.cpp) which itself have other includes. All the examples are Qt applications and provide a *.pro file for qmake (which itself generates a Makefile for make from that .pro file). And passing -x c++ to g++ is rightly not mentioned at all.
You don't compile header files, you compile the C files that include them.
All code in a header file should be declarations and type definitions, which give information to the compiler, but don't actually produce any machine code. That's why there's nothing in your object files.
I am a newer in linux and using ubuntu(4.4.0-64-generic) in vmware fusion. I am learning how to compile kernel. So, I downloaded the kernel(linux-4.4.52.tar.xz) from the kernel.org. But when I input make menuconfig, there are some errors.
root#ubuntu:/usr/src/linux-4.4.52# make menuconfig
HOSTCC scripts/basic/fixdep
In file included from /usr/include/x86_64-linux-gnu/bits/posix1_lim.h:160:0,
from /usr/include/limits.h:143,
from /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/limits.h:168,
from /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/syslimits.h:7,
from /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/limits.h:34,
from scripts/basic/fixdep.c:114:
/usr/include/x86_64-linux-gnu/bits/local_lim.h:38:26: fatal error: linux/limits.h: No such file or directory
compilation terminated.
scripts/Makefile.host:91: recipe for target 'scripts/basic/fixdep' failed
make[1]: * [scripts/basic/fixdep] Error 1
Makefile:444: recipe for target 'scripts_basic' failed
make: * [scripts_basic] Error 2
I have installed headers files and done everything I can do. Someone can help me solve this problem?
You symbolic link is wrong; /usr/src/linux-4.4.0-64-generic/include/linux is the wrong directory and must not be linked to /usr/include/linux.
The kernel has two sets of headers: kernel-internal headers, and user API headers. The latter are inside the uapi directory, and they are what user-space program should see.
When you are compiling your own kernel, you can install the user-space headers of that kernel with make headers_install.
When you are using your distribution's kernel, you can just (re-)install the appropriate package (in your case, linux-headers-generic), and that will do the right thing as long as you do not muck around with those files afterwards.
I've added code to an existing large application and need to make GLib a requirement, as my code relies on it. For development, I just manually edited the Makefile to add
-lglib-2.0
To the LIBS= variable and
-I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include $<
to the line starting with ${CC}.
However, I am at a loss for how to make this permanent/portable in the app -- i.e. when someone executes ./configure in the future, the resulting Makefile should also include the above (as appropriate, since these depend on pkg-config output, I've learned). The codebase I updated includes the following files from the gnu tool chain:
Makefile.in
Makefile.manual
config.h.in
configure
configure.in
I only have a handful of CS degrees and a few years of development experience, so the GNU toolchain remains utterly impenetrable to me. :-/ From googling around, I'm under the impression there should also be a configure.ac file or something where I should add a macro for requiring glib, but no such file is included in the package and I'm at the point of learned helplessness with the whole automake/autoconf/configure/makefile business. Thanks in advance for any advice or pointers!
You should not edit any generated files manually. This includes the final Makefile used to build the application.
In configure.ac, every dependency is listed, thus checking for GLib should go in there. From this file, your final configure shell script is generated.
GLib provides a pkgconfig description so you almost always want to use this to get the correct compile and link flags.
Combining pkgconfig and Autotools is just a matter of calling the PKG_CHECK_MODULES macro. The Autotools Mythbuster is an excellent source that describes how to do it.
In the end it boils down to adding these lines to your configure.ac:
PKG_PROG_PKG_CONFIG
PKG_CHECK_MODULES([GLIB], [glib-2.0])
and these lines to your Makefile.am:
foo_CXXFLAGS = $(GLIB_CFLAGS)
foo_LIBS = $(GLIB_LIBS)