How can I modify vmlinux.lds to break up a built-in.o? - linux

So I'm working with ucLinux under the NXP LPC1788 processor (ARM-CortexM3, no MMU). The ucLinux port was orignally done by Emcraft Systems.
The 1788 has 512KiB of onboard flash (called eNVM) which is faster to access than the rest of memory connected via the external memory controller. Emcraft's linker script has a portion where you can relocate critical parts of the kernel to this eNVM area. I'm using 80K for the bootloader so I have 432K free to stuff with as much kernel as I can.
So the linker script, vmlinux.lds.S, has a portion that begins like this:
#ifdef CONFIG_KERNEL_IN_ENVM
_envm_loc = .;
.envm ENVM_PHYS_OFFSET + CONFIG_KERNEL_IN_ENVM_OFFSET * 1024 : {
_envm_start = .;
#if CONFIG_KERNEL_IN_ENVM_SIZE>0
__exception_text_start = .;
*(.exception.text*)
*(.exception.rodata*)
__exception_text_end = .;
SCHED_TEXT
LOCK_TEXT
KPROBES_TEXT
usr/built-in.o(.text)
usr/built-in.o(.rodata*)
init/built-in.o(.text)
init/built-in.o(.rodata*)
mm/built-in.o(.text)
mm/built-in.o(.rodata*)
...and so on. As you can see, entire subdirectories are being pulled in via their built-in.o object file.
As I get closer and closer to the end of the flash space, I'd like to have a bit more control over what gets linked here. drivers/built-in.o, for example, won't fit in the free space but if I could get drivers/usb and drivers/input here, that would help a lot.
If I modify the linker script to have just those portions, like this:
drivers/usb/built-in.o(.text)
drivers/usb/built-in.o(.rodata*)
drivers/input/built-in.o(.text)
drivers/input/built-in.o(.rodata*)
then I get duplicate symbol errors when drivers/built-in.o gets linked. I can't see where that happens exactly, so that's part of the problem I think.
So the question: Is there a way to link individual built-in.o files to different regions without linking the master .o built at the top of the directory?
I've put the whole linker file at http://pastebin.com/qcj6rHme if anyone wants to take a look.
Thanks!

If you're going to link usb and input directly, drivers/built-in.o should not include them. Modifying Kbuild to build the subdirs but not include them is a bit tricky; those two elements will have to filtered out of obj-y where drivers/built-in.o is generated -- if they aren't included in obj-y they won't get built at all.

Related

Can't add a directory with code to u-boot project

I wanted to call a C function defined in arm-tf (arm trusted firmware) from a u-boot assembly code. That assembly code of u-boot is arch/arm/lib/gic_64.S. The build process for this doesn't work out as I wanted so I ask it here with simple example.
In u-boot build tree, there is the directory arch/arm/lib. I added a directory arch/arm/lib/testd and put testf.c there. testf.c is just printing a string. In arch/arm/lib/Makefile, I added
libs-y += arch/arm/lib/testd
and in arch/arm/lib/testd/Makefile, I added
obj-y += testf.o
When I do make in u-boot root directory, I find nothing is made under arch/arm/lib/testd. But if I do make arch/arm/lib/testd/testf.o, that file is made. I saw this question but it doesn't help. Actually I guess I should see spl/arch/arm/lib/testd/{built-in.o, testf.o} if it was successful(because I'm building u-boot-spl).
I will be very grateful if anyone could tell me how I should do it. Thanks!
It looks like, if I add in arch/arm/lib/Makefile only
obj-y += testd/
Then by doing make I see arch/arm/lib/testd/testf.o and spl/arch/arm/lib/testd/{build-in.o,testf.o} generated.
The key part was the testd/ not testd.

freebsd compile is so complicated?

I want to add custom syscall to freebsd(school work). I google hundreds of time. there is no right solution for it.
my homework is: "Add custom syscall to freebsd kernel and recompile the kernel and use it".
finally I find that I should follow instructions in these two pages:
1 : http://www.onlamp.com/pub/a/bsd/2003/10/09/adding_system_calls.html
then
2: https://www.freebsd.org/doc/en/books/handbook/kernelconfig-building.html
will it shows errors in compile time:
<sys/parma.h> no such file or directory
<sys/kern.h> no such file or directory
<sys/syscallargs.h> no such file or directory
I removed these three header include form my file then recompile it. now shows other errors like: MAXCPU undeclered in pcpu.h file.
what I missed? how can I do my school work?
NOTE: I use freebsd8 in vbox
Look at what the error messages say; the files don't exist.
The first include file is a typo; it's param.h, not parma.h!
There is no kern.h. Maybe you mean sys/kernel.h?
Idem for syscallargs.h. Do you perhaps mean syscall.h?
You can find header files with e.g:
find /usr/src/sys/ -type f -name '*.h'|grep 'sys/.*kern.*\.h'
/usr/src/sys/ofed/include/linux/kernel.h
/usr/src/sys/dev/netmap/netmap_kern.h
...
Update: More important is determining which includes you actually need.
FreeBSD has pretty good documentation. If you want to use a kernel function or data-structure, it is probably covered in section 9 of the manual pages.
You can list all the manual pages in that section with ls /usr/share/man/man9/ | less. Or you can use the apropos command.
Since you want to implement a syscall, start with e.g.
apropos syscall
It will return:
SYSCALL_MODULE(9) - syscall kernel module declaration macro
syscall(2), __syscall(2) - indirect system call
It seems to me that the first one could be relevant to your assignment. (The second one is how to call a system call from user space.) So read it with man SYSCALL_MODULE. Or read it online.
Note that:
A minimal example for a syscall module can be found in
/usr/share/examples/kld/syscall/module/syscall.c.
That example should be enough to get you started on writing your own system call module...
Well take a look at share/examples/kld/syscall for a complete implementation as a module.
Adding a new file to teh kernel is left as an exercise for the reader.
Here is a hint: find the newest added file within kern/* subdir AND CHECK WHAT COMMITS WERE DONE TO MAKE IT COMPILE.
In fact you could have done exactly the same with syscall: FIND THE NEWEST ADDED SYSCALL AND CHECK HOW IT WAS ACHIEVED.
All this is available in svn/git repository history.

how do i add a machine-$(CONFIG_FOO_BAR) for my board info file?

I see that in the directory kernel/arch/arm there are a lot of board files, which I am using as reference for my i2c driver. I have the following code in a directory I made called ./mach-foo and I want to add it to the make file so my driver will work.
Here are the contents:
./mach-foo/foo-dummy.c has module init and exit and a basic i2c struct and probe, does printk's to confirm calls
$ cat ./mach-foo/Makefile
obj-m += foo_dummy.c
Now I need to know how mach-foo will get compiled or built or what ever (my understanding is limited). Looking at the makefile already in place in kernel/arch/arm/Makefile I see that other folders are added via a line similar to
machine-$(CONFIG_FOO_BAR) := foobar
I am familiar with the operation of Kconfig, and that it decideds what come with CONFIG_FOO_BAR
I was hoping that I could just hard-code a line like
machine-m :=foo does this work?
I saw that the Makefile automatically appends mach- to the name here, so are machine-m or machine-y valid?
Also, do I need := or +=?

Linux Module file missing

Actually I'm a beginner and I'm trying to learn the concept of low-level driver and high level driver. I want to know how a module depends on other modules for their operation.
I've done lsmod command. I found these lines in the output.
parport_pc 25962 1
lp 7028 0
parport 32635 3 ppdev,parport_pc,lp
From the above lines, I understood that there exist modules like,
parport_pc
lp
parport
I've found source code parport_pc.c, lp.c, in the directory /usr/src/drivers/parport. But I can't find the source code for parport in my entire file system. Even though I found parpot.ko inside /lib/modules/linux2.6.32-37-generic/kernel/parport.
Also in the directory /usr/src/drivers/parport, I've seen a line in the Makefile like,
obj-$(CONFIG_PARPORT) += parport.o
So where can I find the parport.c file ? I've searched the entire file system using the command
find / -name parport.c
but no result. Why is the file parport.c missing?
The parport.o file is compiled from multiple .c files, including share.c, ieee1284.c, ieee1284_ops.c, and procfs.c, and possibly including daisy.c and probe.c, all under the drivers/parport/ directory of the Linux sources. (This information was taken from Linux 3.5-rc3-00203-g8874e81, which is a bit newer than the kernel you are looking at, but the parallel port drivers don't change much any more).
To find this information, I looked at the same Makefile and noted that the parport-objs variable was initially set to share.o ieee1284.o ieee1284_ops.o procfs.o and daisy.o probe.o was added if CONFIG_PARPORT_1284 was set to y.

is there a way to change the target of symlink /proc/self/exe?

hi all:
recently i'm working on make checkpoint on linux process and encountered a problem,it looks like that when i munmap memory map of the executable to current process,the symlink /proc/self/exe is dead.what i want is to make this symlink pointing to a other executable(the one for my resumed processs),is that possible?i tried delete it and recreate, permission denied. english is not my native language, i hope i've made my point,thanx
prctl(PR_SET_MM_EXE_FILE, ...)
Supersede the /proc/pid/exe symbolic link with a new one pointing to a new executable file identified by the file descriptor provided in arg3 argument. The file descriptor should be obtained with a regular open(2) call.
No. /proc is completely managed by the kernel and does not allow changes like that.
But you may be able to start a new process (with fork() perhaps) and map your memory snapshot into that.

Resources