Greeting everyone on stackoverflow!
I am trying to add fpirntf() to XNU kernel tcp_xxx.c file, so when TCP moves it can print parameters to a file, for better understanding how TCP works, but fatal error occurs like follows:
$ sudo make ARCH_CONFIGS=X86_64 KERNEL_CONFIGS=DEBUG
CC tcp_output.o
/Users/wangweikai/Desktop/xnubuilder/xnu-2422.90.20/bsd/netinet/tcp_output.c:135:10: fatal error: 'stdio.h' file not found
#include <stdio.h>
^
1 error generated.
make[7]: *** [tcp_output.o] Error 1
make[6]: *** [build_all] Error 2
make[5]: *** [do_all] Error 2
make[4]: *** [build_all] Error 2
make[3]: *** [build_all_recurse_into_conf] Error 2
make[2]: *** [build_all_recurse_into_bsd] Error 2
make[1]: *** [build_all_bootstrap_DEBUG^X86_64^NONE] Error 2
make: *** [all] Error 2
It looks there is no stdio.h in xnu source code, to solve this I re-installed xcode 5.0.2(only this works with xnu-2422) and outputs mach_kernel able to boot; I tried install command line tools by "xcode-select --install" in terminal, but not working neither.
BTW if I add printf() without #include it gives no error, it looks print function is defined by file with name other than stdio.h.
Since my point is to log how TCP parameters(such as congestion window size and next sequence number and so on)changes in a file, so if there is any way can do this please also tell me, I am total new to xnu and C programming.
Best regards.
Standard I/O (i.e, stdio) is not available in the kernel. To output debugging information from the kernel, call printf(); its output will be visible in the kernel log. Writing data to files directly from the kernel is complicated, and is rarely advisable. (In this case, it may in fact lead to hard lockups, e.g, if the file being written to is on a network volume!)
If you are new to C programming, this is not a good first project. Kernel development is difficult, unforgiving stuff, particularly for the XNU kernel; errors will often cause your computer to crash, potentially losing data, and debugging services are often not available. If you have your heart set on examining an OS kernel, though, the Linux kernel is much easier to work with — it can be easily booted and debugged in a virtual machine, and is far better documented.
Related
I am working on this piece of code, trying to learn basic C programming.
I managed to compile and run a basic program.
Then, when I try to run a code on which the compiler raises an error, the problem starts -- from then on I get:
c:/mingw/bin/../lib/gcc/mingw32/4.9.3/../../../../mingw32/bin/ld.exe: cannot open output file tests.exe: Permission denied
collect2.exe: error: ld returned 1 exit status
mingw32-make.exe[3]: *** [tests.exe] Error 1
mingw32-make.exe[2]: *** [CMakeFiles/tests.dir/all] Error 2
No matter what I change to code to, even to just a basic int main() {return 0;} code, I keep getting that problem.
Edit (integrated from comment):
Found the solution, I had the program still running and I had to manually stop it. I am used to python/java, where once you get an error the program stops. Should it not be like that in C as well?
I assume the error that triggers the linker failure later on is actually a runtime error, not a compiler one.
As you have found out, Windows cannot overwrite a file which is opened in a running program (or is the running program itself), hence the error when ld.exe (the linker) tries to create a new executable.
The most probable cause is that you are starting your program in debug mode (the green beetle icon) instead of a normal run (the green "play" arrow). This attaches a debugger (probably gdb) to your program. When your program crashes, the debugger stops it in its tracks and waits for you to investigate, thus keeping the process alive.
Make sure the debug tools are not hidden in some way, or just launch your program without a debugger when you want it to fail fast.
I try to execute fakeroot debian/rules binary-headers binary-genericand compile when building kernel but get the error.
Here error in below
arch/x86/built-in.o:(.rodata+0x1cb8): undefined reference to 'sys_monlak'
make[2]: *** [vmlinux] Error 1
make[2]: Leaving directory '/home/su/linux-lts-vivid-3.19.0/debian/build/build-generic'
make[1]: *** [sub-make] Error 2
make[1]: Leaving directory '/home/su/linux-lts-vivid-3.19.0'
make: *** [/home/su/linux-lts-vivid-3.19.0/debian/stamps/stamp-build-generic] Error 2
I tried to build kernel following Build your own kernel and Clarkson.edu
I don't see any reference to the symbol "sys_monlak" inside any branch of the official Linux kernel. Are you using a branch obtained from somewhere else?
This error would happen if a driver depends on a symbol "sys_monlak" which should be defined elsewhere in the kernel but isn't, or perhaps the correct kernel module isn't enabled in the kernel config.
You can try running:
$ grep -R "sys_monlak"
If this produces a c file then you can then try to find the Makefile which should compile in this c file. If, for example, the file was called "arch/x86/monlak.c" you might find the following in the file "arch/x86/Makefile":
obj-$(CONFIG_MONLAK) += monlak.o
In this case you would want to try to enable CONFIG_MONLAK in the kernel config.
The other possibility is that you might want to disable the module that depends on the symbol 'sys_monlak'. Try to carefully read the description in the Kconfig file to see what each module does (the one that depends and the one that provides).
I am fairly new to programming and have mostly programmed using textfiles but now I am supposed to start using CodeLite for an assignment. I am using windows 10 64-bit.
The problem is that I cannot seem to get my compiler to work in codelite the error message I receive is this:
C:\WINDOWS\system32\cmd.exe /C C:/TDM-GCC-32/bin/mingw32-make.exe -j4 SHELL=cmd.exe -e -f Makefile
"----------Building project:[ hello - Debug ]----------"
mingw32-make.exe[1]: Entering directory 'C:/codelitews/hello'
'makedir' is not recognized as an internal or external command, operable program or batch file.
mingw32-make.exe[1]: *** [Debug/.d] Error 1
mingw32-make.exe[1]: *** Waiting for unfinished jobs....
hello.mk:88: recipe for target 'Debug/.d' failed
built-in: fatal error: opening dependency file ./Debug/main.c.o.d: No such file or directory
compilation terminated.
mingw32-make.exe[1]: *** [Debug/main.c.o.d] Error 1
hello.mk:99: recipe for target 'Debug/main.c.o.d' failed
mingw32-make.exe[1]: Leaving directory 'C:/codelitews/hello'
mingw32-make.exe: *** [All] Error 2
Makefile:4: recipe for target 'All' failed
====1 errors, 0 warnings====
And I cannot figure out what this means and why it happens since the same compiler works just fine with codeblocks. I have tried googling this issue but have not found something useful. Help would be much appreciated.
Thanks.
CodeLite should be able to recognize makedir.exe it is located under the same folder where you installed codelite.exe
If it does not, then it means that something terribly went wrong, usually this happens when you start modifying the PATH environment variable without knowing what you are doing.
Can you please paste the content of your environment variable (from within CodeLite). From the main menu, go to: Settings->Environment Variables and paste here the content of the text box
Eran
I am trying to modify the dynamic linker provided in the libc6(2.15-0ubuntu20.2) on a 64 bit Ubuntu machine.
So currently my code is using the same version of the glibc library. (I have downloaded the source code for the same and working on it). My question is that is it possible to modify and build only the linker source code which is present in glibc\elf\ directory without building the entire glibc library.
And if it is possible how can I make my test program to switch using the new version of dynamic linker that I have build myself instead of using the default unmodified linker.
Any pointers or suggestions are highly appreciated.
(If any more information is needed please let me know)
EDIT::
#constantius
I followed the steps in the post linked by you to build ld.so.
But I am getting following error on the make and I checked ld.so is not there in the elf.
The error is::
/var/services/homes/abhi/test/ld/eglibc-build/elf/librtld.os: In function `generic_getcwd':
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:356: undefined reference to `__closedir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:368: undefined reference to `__fdopendir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:384: undefined reference to `__readdir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:397: undefined reference to `rewinddir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:528: undefined reference to `__closedir'
/var/services/homes/abhi/test/ld/eglibc-2.15/elf/../sysdeps/posix/getcwd.c:490: undefined reference to `__closedir'
collect2: error: ld returned 1 exit status
make[2]: *** [/var/services/homes/abhi/test/ld/eglibc-build/elf/ld.so] Error 1
make[2]: Leaving directory `/var/services/homes/abhi/test/ld/eglibc-2.15/elf'
make[1]: *** [elf/subdir_lib] Error 2
make[1]: Leaving directory `/var/services/homes/abhi/test/ld/eglibc-2.15'
make: *** [all] Error 2
NOTE With the same infrastructure I can build and install the full GLIBC so I dont think there is an error with the infrastructure.
-- I guess the error is some where related to editing Makeconfig to all-subdirs = csu elf gmon io misc posix setjmp signal stdlib string time.
--Any suggestions on this..
SOLVED
Need to add dirent in the all-subdirs list in addition to what we edited before
Thanks
Citing this page. In case you don't get something, comment please — I'll try to explain.
Building
To compile Glibc (ld.so cannot be compiled independently) download and unpack Glibc source tarball.
1 Make sure the version of Glibc you downloaded is the same as the system's current one.
2 Make sure the environmental variable LD_RUN_PATH is not set.
3 Read the INSTALL and make sure all necessary tool chains (Make, Binutils, etc) are up-to-date.
4 Make sure the file system you are doing the compilation is case sensitive, or you will see weird errors like
/scratch/elf/librtld.os: In function `process_envvars':
/tmp/glibc-2.x.y/elf/rtld.c:2718: undefined reference to `__open'
...
5 ld.so should be compiled with the optimization flag on (-O2 is the default). Failing to do so will end up with weird errors (see Question 1.23 in FAQ)
6 Suppose Glibc is unpacked at
/tmp/glibc-2.x.y/
Then edit /tmp/glibc-2.x.y/Makefile.in: Un-comment the line
# PARALLELMFLAGS = -j 4
and change 4 to an appropriate number.
7 Since we are only interested in ld.so and not the whole Glibc, we only want to build the essential source files needed by ld.so. To do so, edit /tmp/glibc-2.x.y/Makeconfig: Find the line started with
all-subdirs = csu assert ctype locale intl catgets math setjmp signal \
...
and change it to
all-subdirs = csu elf gmon io misc posix setjmp signal stdlib string time
8 Find a scratch directory, say /scratch. Then
$ cd /scratch
$ /tmp/glibc-2.x.y/configure --prefix=/scratch --disable-profile
$ gmake
Since we are not building the entire Glibc, when the gmake stops (probably with some errors), check if /scratch/elf/ld.so exists or not.
ld.so is a static binary, which means it has its own implementation of standard C routines (e.g. memcpy, strcmp, etc) It has its own printf-like routine called _dl_debug_printf.
Testing
You can run the ld-linux.so directly. It will complain that this is probably not what you want (but you want exactly this) and offer you list of options with which you can run it. See also man ld-linux.so for debugging flags, i.e. there's LD_DEBUG environment variable you can define to see ld-linux.so debugging output.
While I'm not clear on whether the build system for glibc makes doing this easy, there's no fundamental reason why you can't build and use the glibc dynamic linker without building libc.so. I would peruse the top-level Makefile for ways to make this work.
As for testing it, there are two methods:
Explicitly invoke the dynamic linker to run a program, as in:
./ld-linux.so.2 a.out args ...
When linking your program, specify an alternate dynamic linker pathname (which will get stored in its PT_INTERP program header) by passing this option to the compiler driver:
-Wl,-dynamic-linker,/path/to/alternate/ld-linux.so.2
I would like to write a linux block device driver. The driver would not need to access the hardware so it can be in userspace.
To start, I have tried to build an example block device driver with this Makefile:
obj-m = sbd.o
KVERSION = $(shell pwd)
PWD = $(shell pwd)
all:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
I however get these errors which I do not know how to fix. Here is the stdout and stderr:
make -C /lib/modules/2.6.31-19-generic/build M=/home/andreas/sp/nivoa/src/driver/sbd modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.31-19-generic'
CC [M] /home/andreas/sp/nivoa/src/driver/sbd/sbd.o
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c:72: error: expected ‘)’ before ‘*’ token
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c:128: warning: initialization from incompatible pointer type
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c: In function ‘sbd_init’:
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c:143: error: ‘sbd_request’ undeclared (first use in this function)
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c:143: error: (Each undeclared identifier is reported only once
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c:143: error: for each function it appears in.)
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c:146: error: implicit declaration of function ‘blk_queue_hardsect_size’
make[2]: *** [/home/andreas/sp/nivoa/src/driver/sbd/sbd.o] Error 1
make[1]: *** [_module_/home/andreas/sp/nivoa/src/driver/sbd] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-2.6.31-19-generic'
make: *** [all] Error 2
Any help on this would be greatly appreciated.
Thanks,
Andreas
There isn't an "official" way of doing block drivers in userspace, however people often do it by (ab)using the NBD driver to talk over a loopback network to a daemon which listens on a normal socket and speaks the NBD protocol. See the NBD docs for more info.
Your example is for a kernel-mode block device, which will need to be built as a kernel module. And as the kernel internals are always changing, it's presumably now incompatible.
Following MarkR's suggestion, it is even possible to talk the NBD protocol over an AF_UNIX socket pair, so no extra local daemon is needed. The program implementing this protocol will need to set up the socket pair and fork off a child. Both parent and child close one end of the socket pair. One of them starts taking requests on its end of the socket while the other one connects the NBD driver to its end of the socket.
Always looks at the first error:
In your case it looks like a problem with include files, e.g. request_queue_t is not defined.
Since this is a deprecated type, you are probably using a version of linux/blkdev.h that is newer than the code example.
Try adding typedef struct request_queue request_queue_t;
While using NBD, as suggested before, is nice, maybe a better way (used by, for example, virtualbox-fuse) is to make a FUSE filesystem that exports one file, which you can then use via losetup.
You can use NBD. Using nbdkit you can even write virtual block devices in shell script or other scripting languages (although stick to C if you want the best performance). I gave a talk about this topic at FOSDEM 2019 where I did a live demo writing a Linux kernel block device in shell script.
In addition to the above useful answers I would like to add that apart from NBD, there are also other ways where Linux Block I/O Layer can be used at userspace. Following are the additional options:
TCMU (TCM in Userspace) helps implementing custom SCSI (Small Computer System Interface) targets (block device) in user space.
BUSE (block device in userspace) build on the idea of Filesystem in Userspace (FUSE) allows the virtual block devices to run in userspace as well.