device driver missing config.h - c

So I start reading the book http://lwn.net/Kernel/LDD3/ to write device driver
The problem is the book used 2.6.10 while I'm using 2.6.35.X (on Ubuntu) and "config.h" is missing. I googled the problem and it turned out that config.h is removed.
http://stephane.lesimple.fr/wiki/blog/kernel_2.6.18_linux_config.h_problem suggests 3 solutions and the first 2 don't work to me ( I don't have autoconf.h ). The 3rd solution is the one that is over my head. If anyone can explain the 3rd or has other solutions, I'd appreciate.
Thanks

All -imacros file and -include
file options are processed after all -D and -U options1.
Each (of the three) option is a way of pointing GCC to a text file with a list of preprocessor defines.
To use option 3, -imacros a_file , there is still a need for the file a_file , (ie: autoconf.h), the file with the macros or configuration definitions. On this system it's /usr/src/linux/include/generated/autoconf.h
l /usr/src/linux
lrwxrwxrwx 1 root conman 23 Nov 29 19:37 /usr/src/linux -> linux-2.6.35-gentoo-r12
As you can see, this file can occur in 2.6.35. It seems that maybe configuringi the kernel makes this file; because the content of this file looks tailored to the current kernel. This looks like a file declaring which drivers are compiled-in(as apposed to compiled as modules).
So:
First check for the file find /usr/src/linux/. -name autoconf.h
If it is not there, then configure the kernel (then check again)
Change CFLAGS in the device driver's Makefile to include -imacros /usr/src/linux/include/generated/autoconf.h
CFLAGS+=-imacros /usr/src/linux/include/generated/autoconf.h
Comment out #include <config.h> from the driver sources.
1 "3.11 Options Controlling the Preprocessor," GCC Reference

Related

Windres not compiling .rc file no matter what I do

So I am making a desktop application using C and the Win32 API. I am also using CMake/Make in conjunction with MinGW. Everything went smoothly until I wanted to add an .rc file to the executable. From my understanding you write an .rc file which is then compiled to a .res file, then presumably you are supposed to embed it in the executable. Here's the problem however, when I attempt to compile the .rc file with the GNU utility windres it fails to compile. I always get the following error messages:
C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin\windres.exe: can't open file `page:': Invalid argument
C:\Code\C\test\resources.rc:4: fatal error: when writing output to : No such file or directory
4 | IDI_TEST_ICON ICON "test.ico"
|
compilation terminated.
C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin\windres.exe: preprocessing failed.
This occurs with every .rc file I've tried, for completeness however, here is the current test file I am trying to compile:
#include <windows.h>
#include "resource.h"
IDI_TEST_ICON ICON "test.ico"
And the resource.h file:
#define IDI_TEST_ICON 101
So the final question is the following: Why doesn't windres compile the .rc file successfully? And what can I do about in the context of using MinGW?
Edit 1:
Worth noting is that I also converted the .rc file to ANSI format since windres is notorious for yielding peculiar errors when formatted in UTF-8. Yet, the same errors occur.
windres actually generates an object file (in COFF format)
So you should run the command like this:
windres resource.rc -o resource.o
When I check the format of the generated file like this:
file resource.o
I get the following result:
resource.o: Intel amd64 COFF object file, no line number info, not stripped, 1 section, symbol offset=0x3c4c, 1 symbols
So you just need to include the generated .o file in the link step to include the resource.
For example when you run the following command you will get an .exe that won't run, but it will show the icon in Explorer:
gcc -shared -o resource.exe resource.o
After a lot of digging in old forum threads I managed to find a "solution" that works. However I still find it peculiar that this solves the problem. I followed Brecht Sanders advise and downloaded a standalone build from winlibs.com. Even this didn't solve the problem which led me to investigate possible RC_COMPILER_FLAGS which ultimately led me to the --use-temp-file flag.
This flag acts as an alternate approach to compile .rc files since it excludes the use of popen (or the equivalent of it in Windows). According to the documentation this flag should be used if the implemenation of popen is buggy on the host. What is interesting here is that the documentation states that this is known to happen on certain non-english versions of Windows. In my case I am using the Swedish language version of Windows which might explain why this is occuring.
Thus the final solution turns out to be:
windres -i resource.rc -o resource.o --use-temp-file
Which ultimately yields an object file which can then be included in the add_executable call in CMake.

gcc compiles ELF file with wrong search list

After compiling gcc and using it to compile a simple c program:
echo 'int main(){}' > dummy.c
cc dummy.c -v -Wl,--verbose &> dummy.log
grep -B4 '^ /usr/include' dummy.log
the result is:
ignoring nonexistent directory "/tools/lib/gcc/x86_64-pc-linux-gnu/9.2.0/../../../../x86_64-pc-linux-gnu/include"
ignoring duplicate directory "/tools/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/include
but according to Linux From Scratch guide 9.1 in section 6.25 "Verify that the compiler is searching for the correct header files:" the following is expected (ignoring the *linux-gnu paths...):
#include <...> search starts here:
/usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/include
/usr/local/include
/usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/include-fixed
/usr/include
What's even worse is that
grep 'SEARCH.*/usr/lib' dummy.log |sed 's|; |\n|g'
is:
SEARCH_DIR("/usr/lib");
but should be:
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib64")
SEARCH_DIR("/usr/local/lib64")
SEARCH_DIR("/lib64")
SEARCH_DIR("/usr/lib64")
SEARCH_DIR("/usr/x86_64-pc-linux-gnu/lib")
SEARCH_DIR("/usr/local/lib")
SEARCH_DIR("/lib")
SEARCH_DIR("/usr/lib");
I've tried to add all paths to /etc/ld.so.conf and recompiled gcc pass 2, but nothing changed.
So what exactly determines the SEARCH_DIR entries in an ELF file?
EDIT1: I backtracked and found out that the previous step make -k clean did not finish because it's missing autogen, which is not covered at all in the LFS guide 9.1 it seems.
I restarted LFS 9.1 and followed the instruction with more care, now the output is as expected!
There are two things I did differently:
In my first attempt I ignored the advice on chapter 5 to remove extracted tarballs after each section:
For each package:
Using the tar program, extract the package to be built. In Chapter 5, ensure you are the lfs user when extracting the package.
Change to the directory created when the package was extracted.
Follow the book's instructions for building the package.
Change back to the sources directory.
Delete the extracted source directory unless instructed otherwise.
When I reinstalled the host OS I didn't create it with lfs as first user. Instead I created it with lfshost user and created the user lfs as described in section 4.3

Difference in netinet/tcp.h Vs linux/tcp.h

I am trying to use the TCP option TCP_USER_TIMEOUT which was added to linux in 2.6.37.
Apprently my C source includes the netinet/tcp.h instead of linux/tcp.h. And TCP_USER_TIMEOUT is defined in linux/tcp.h and not in netinet/tcp.h I read here that user space apps should NOT include any header from linux/ (like in this case linux/tcp.h). But that link doesn't explain why.
Your source is incorrect, and a bulletin board is hardly a definitive source.
You should not include header files from the linux directory unless you are trying to include linux specific functions which are only to be found by including header files from the linux directory.
In relation to TCP_USER_TIMEOUT, the man-page for TCP notes in respect of many of the options 'This option should not be used in code intended to be portable'. Whilst it does not note this in respect of TCP_USER_TIMEOUT, it is a linux-only option as far as I understand it.
However, in this case:
$ grep -r TCP_USER_TIMEOUT /usr/include
/usr/include/netinet/tcp.h:#define TCP_USER_TIMEOUT 18 /* How long for loss retry before timeout */
/usr/include/linux/tcp.h:#define TCP_USER_TIMEOUT 18 /* How long for loss retry before timeout */
at least in my include files, it's present in both files. Perhaps you need to update your includes.

Problems with linking a library with a c program in linux

I want to run serial commands from a Bealgebone to a 4Dsystems display. Therefore I copied the c library found here into a directory and created a test program main.c:
#include "Picaso_const4D.h"
#include "Picaso_Serial_4DLibrary.h"
int main(int argc,char *argv[])
{
OpenComm("/dev/ttyUSB0", B115200); // Matches with the display "Comms" rate
gfx_BGcolour(0xFFFF);
gfx_Cls();
gfx_CircleFilled(120,160,80,BLUE);
while (1) {}
}
Now when I do gcc -o main main.c its says
main.c:2:37: fatal error: Picaso_Serial_4DLibrary.h: No such file or
directory
So I try linking it:
gcc main.c -L. -lPICASO_SERIAL_4DLIBRARY
which gives me the same error. Then I tried to create a static library:
gcc -Wall -g -c -o PICASO_SERIAL_4DLIBRARY PICASO_SERIAL_4DLIBRARY.C
which gives me this:
PICASO_SERIAL_4DLIBRARY.C:1:21: fatal error: windows.h: No such file
or directory compilation terminated.
What am I doing wrong? the git page clearly says this library is created for people who do not run windows.
Thanks in advance!
You're not getting a linker error; you're getting a preprocessor error. Specifically, your preprocessor can't find Picaso_Serial_4DLibrary.h. Make sure that it's in your include path; you can add directories to your include path using the -I argument to gcc.
You've had two problems. First was the picaso_whatever.h file that couldn't be found. You fixed that with the -I you added. But, now, the picaso.h wants windows.h
What are you building on? WinX or BSD/Linux?
If you're compiling on WinX, you need to install the "platform sdk" for visual studio.
If you're using mingw or cygwin, you need to do something else.
If on WinX, cd to the C: directory. Do find . -type f -name windows.h and add a -I for the containing directory.
If under Linux, repeat the find at the source tree top level. Otherwise, there is probably some compatibility cross-build library that you need to install.
Or, you'll have to find WinX that has it as Picaso clearly includes it. You could try commenting out one or more of the #include's for it and see if things are better or worse.
If you can't find a real one, create an empty windows.h and add -I to it and see how bad [or good] things are.
You may need the mingw cross-compiler. See https://forums.wxwidgets.org/viewtopic.php?t=7729
UPDATE:
Okay ... Wow ... You are on the right track and close, but this is, IMO, ugly WinX stuff.
The primary need of Picaso is getting a serial comm port connection, so the need from within windows.h is [thankfully] minimal. It needs basic boilerplate definitions for WORD, DWORD, etc.
mingw or cygwin will provide their own copies of windows.h. These are "clean room" reimplementations, so no copyright issues.
mingw is a collection of compile/build tools that let you use gcc/ld/make build utilities.
cygwin is more like: I'd like a complete shell-like environment similar to BSD/Linux. You get bash, ls, gcc, tar, and just about any GNU utility you want.
Caveat: I use cygwin, but have never used mingw. The mingw version of windows.h [and a suite of .h files that it includes underneath], being open source, can be reused by other projects (e.g. cygwin, wine).
Under Linux, wine (windows emulator) is a program/suite that attempts to allow you to run WinX binaries under Linux (e.g. wine mywinpgm).
I git cloned the Picaso library and after some fiddling, I was able to get it to compile after pointing it to wine's version of windows.h
Picaso's OpenComm is doing CreateFile [a win32 API call]. So, you'll probably need cygwin. You're opening /dev/ttyUSB0. /dev/* implies cygwin. But, /dev/ttyUSB0 is a Linux-like name. You may need some WinX-style name like "COM:" or whatever. Under the cygwin terminal [which gives you a bash prompt], do ls /dev and see what's available.
You can get cygwin from: http://cygwin.com/ If you have a 64 bit system, be sure to use the 64 bit version of the installer: setup-x86_64.exe It's semi-graphical and will want two directories, one for the "root" FS and one to store packages. On my system, I use C:\cygwin64 and C:\cygwin64_packages--YMMV.
Note that the installer won't install gcc by default. You can [graphically] select which packages to install. You may also need some "devel" packages. They have libraries and .h files that a non-developer wouldn't need. As, docs mention, you can rerun the installer as often as you need. You can add packages that you forgot to specify or even remove ones that you installed that you don't need anymore.
Remember that you'll need to adjust makefile -I and/or -L option appropriately. Also, when building the picaso library, gcc generated a ton of warnings about overflow of a "large integer". The code was doing:
#define control_code -279
unsigned char buf[2];
buf[0] = control_code >> 8;
buf[1] = control_code;
The code is okay, and the warning is correct [because the code is sloppy]. If the code had done:
#define control_code -279
unsigned char buf[2];
buf[0] = (unsigned) control_code >> 8;
buf[1] = (unsigned) control_code;
it probably would have been silent. Use -Wno-overflow in your Makefile to get rid of the warnings rather that edit 50 or so lines

How do I access a header file/find its location?

I'm running through some source code that I was given, but I'm accessing it through SSH. It includes a header file or two which i'm not familiar with and I don't believe is part of the C libraries that are provided.
Is there a way that I can do this? Where should I look in the system files to see what this header file contains?
The top of the file reads:
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include "support.h"
But there is no support.h file in the .c file's directory...where could it be?
You can try find <project-root-dir> -name support.h. It's likely to be in a directory like include, but of course could be anything. Also if it builds, you can look at the compile command and see what -I directories are supplied. As a last resort you can try locate support.h or find / -name support.h.
Apart form searching the filesystem with either find or locate, if you have access to the makefile, you should find the information in the compilation line after in a -I argument.

Resources