who can explain what does the following code means?
if __KERNEL__ is not defined, define following macros.
when and where define __KERNEL__ ?
/* only for userspace compatibility */
#ifndef __KERNEL__
/* IP6 Hooks */
/* After promisc drops, checksum checks. */
#define NF_IP6_PRE_ROUTING 0
/* If the packet is destined for this box. */
#define NF_IP6_LOCAL_IN 1
/* If the packet is destined for another interface. */
#define NF_IP6_FORWARD 2
/* Packets coming from a local process. */
#define NF_IP6_LOCAL_OUT 3
/* Packets about to hit the wire. */
#define NF_IP6_POST_ROUTING 4
#define NF_IP6_NUMHOOKS 5
#endif /* ! __KERNEL__ */
When you compile your kernel, __KERNEL__ is defined on the command line.
User-space programs need access to the kernel headers, but some of the info in kernel headers is intended only for the kernel. Wrapping some statements in an #ifdef __KERNEL__/#endif block ensures that user-space programs don't see those statements.
I used Google to search for __KERNEL__ and found this.
The __KERNEL__ macro is defined because there is programs (like libraries) than include kernel code and there is many things that you don't want them to include. So most modules will want the __KERNEL__ macro to be enabled.
The same code is used in userspace iptables application (and possibly glibc and others), hence there is a protection for non-kernel code.
Related
I'm developing an EGT embedded Linux application on a Microchip SAM Xplained Board. EGT is primarily C++ based, similar in some respects to Qt. The application I'm building naturally contains the GUI element & the interaction with hardware connected to the board.
For speed & convenience I'd like to develop as much as possible of the GUI on a desktop (EGT will run on a desktop Linux machine), however I'm going to run into issues when hardware interaction occurs (e.g. calls to GPIO pins etc.)
Is there a gcc compile time option to somehow block/redirect/overwrite these hardware interactions to something that would allow the application to run on a desktop? If not I think I'm looking at lots of #if arch = 'ARM' or something similar.
Thanks for looking!
Regards,
For anyone looking at this it seems that the way to go is some type of wrapper around hardware calls (examples below) as suggested by #sawdust or using a QEMU (which can be built using Yocto)
// Enable compiling on desktop
#if defined(__x86_64__) || defined(_M_X64)
#pragma GCC diagnostic ignored "-Wunused-value"
#define GPIO_CHIP_GET_LINE(chip, offset) (NULL)
#define GPIO_CHIP_OPEN_BY_NAME(port, pin) (1)
#define GPIO_LINE_REQUEST_OUTPUT(line, consumer, default_val) (1)
#define GPIO_LINE_REQUEST_INPUT(line, consumer) (1)
#define GPIO_LINE_SET_VALUE(line, value) (1)
#define GPIO_LINE_GET_VALUE(line) (1)
#else
#define GPIO_CHIP_GET_LINE(chip, offset) gpiod_chip_get_line(chip, offset)
#define GPIO_CHIP_OPEN_BY_NAME(name) gpiod_chip_open_by_name(name)
#define GPIO_LINE_REQUEST_OUTPUT(line, consumer, default_val) gpiod_line_request_output(line, consumer, default_val)
#define GPIO_LINE_REQUEST_INPUT(line, consumer) gpiod_line_request_input(line, consumer)
#define GPIO_LINE_SET_VALUE(line, value) gpiod_line_set_value(line, value)
#define GPIO_LINE_GET_VALUE(line) gpiod_line_get_value(line)
#endif
While executing in the kernel mode, is there any way to get the userspace CR3 value when Page Table Isolation(PTI) is enabled?
In current Linux, see arch/x86/entry/calling.h for asm .macro SWITCH_TO_USER_CR3_NOSTACK and other stuff to see how Linux flips between kernel vs. user CR3. And the earlier comment on the constants it uses:
/*
* PAGE_TABLE_ISOLATION PGDs are 8k. Flip bit 12 to switch between the two
* halves:
*/
#define PTI_USER_PGTABLE_BIT PAGE_SHIFT
#define PTI_USER_PGTABLE_MASK (1 << PTI_USER_PGTABLE_BIT)
#define PTI_USER_PCID_BIT X86_CR3_PTI_PCID_USER_BIT
#define PTI_USER_PCID_MASK (1 << PTI_USER_PCID_BIT)
#define PTI_USER_PGTABLE_AND_PCID_MASK (PTI_USER_PCID_MASK | PTI_USER_PGTABLE_MASK)
It looks like the kernel CR3 is always the lower one, so setting bit 12 in the current CR3 always makes it point to the user-space page directory. (If the current task has a user-space, and if PTI is enabled. These asm macros are only used in code-paths that are about to return to user-space.)
.macro SWITCH_TO_USER_CR3_NOSTACK scratch_reg:req scratch_reg2:req
...
mov %cr3, \scratch_reg
...
.Lwrcr3_\#:
/* Flip the PGD to the user version */
orq $(PTI_USER_PGTABLE_MASK), \scratch_reg
mov \scratch_reg, %cr3
These macros are used in entry_64.S, entry_64_compat.S, and entry_32.S in paths that returns to user-space.
There's presumably a cleaner way to access user-space page tables from C.
Your best bet might be to look at the page-fault handler to find out how it accesses the process's page table. (Or mmap's implementation of MAP_POPULATE).
I am working on a small program to learn how to mix C and Assembly in Atmel Studio GCC. Basically I am writing a C program to initiate the stack pointer in assembly. When I build it I keep getting an error "Operand out of range". I've initiated stack pointers many times in programs but can't get it to work in the ".s" file of this program. I've gotten the program to work with different register in the ".s" file so I don't think it's the connection between the two files. Any help would be appreciated.
Main.c:
#define F_CPU 16000000
#include <avr/io.h>
#include <util/delay.h>
extern void setStackPointer(void);
int main(void)
{
DDRB |= 0x20;
setStackPointer();
while (1)
{
PORTB = 0x20;
_delay_ms(500);
PORTB = 0x00;
_delay_ms(500);
}
}
Assembler1.s:
#define _SFR_ASM_COMPAT 1
#define _SFR_OFFSET 0
#include <avr/io.h>
.global setStackPointer
setStackPointer:
ldi r18, lo8(RAMEND-0x20)
out SPL, R18
ldi R18, hi8(RAMEND-0x20)
out SPH, R18
ret
There are several issues here.
First, the comment by Sir Jo Black is right: there is no reason to
subtract 0x20 from RAMEND. I mean, unless you want to set apart 32
bytes at the end of the RAM...
Second, there is no point in setting the stack pointer yourself. On most
recent AVRs, including the ATmega328P, SP is automatically initialized
by the hardware with RAMEND. C.f. the datasheet. If that weren't
enough, it is initialized again by the C runtime, which gets normally
linked into your program (even a 100% assembly program) if you compile
it with gcc.
Third, from the avr-libc documentation:
For more backwards compatibility, insert the following at the start of
your old assembler source file:
#define __SFR_OFFSET 0
This automatically subtracts 0x20 from I/O space addresses, but it's a
hack, so it is recommended to change your source: wrap such addresses
in macros defined here, as shown below. After this is done, the
__SFR_OFFSET definition is no longer necessary and can be removed.
The recommended way to write that code is then:
setStackPointer:
ldi r18, lo8(RAMEND)
out _SFR_IO_ADDR(SPL), r18
ldi r18, hi8(RAMEND)
out _SFR_IO_ADDR(SPH), r18
ret
If you really want to use the old hack, write
#define __SFR_OFFSET 0
at the beginning of your program. And pay attention to the double
underscore at the beginning of the macro name.
What is the difference between the vma_flags VM_IO and VM_RESERVED? How should they be used?
The comments in linux kernel source code is very confusing
http://lxr.free-electrons.com/source/include/linux/mm.h?v=3.4;a=arm#L104
http://lxr.free-electrons.com/source/include/linux/mm.h?v=3.4;a=arm#L96
#define VM_IO 0x00004000 /* Memory mapped I/O or similar */
#define VM_RESERVED 0x00080000 /* Count as reserved_vm like IO */
Thanks
From: http://www.makelinux.net/ldd3/chp-15-sect-1
"VM_IO marks a VMA as being a memory-mapped I/O region. Among other things, the VM_IO flag prevents the region from being included in process core dumps.
VM_RESERVED tells the memory management system not to attempt to swap out this VMA; it should be set in most device mappings."
For better understanding of how and why these evolved and what is the linux kernel community's recommendation, read these lwn articles:
http://lwn.net/Articles/161204/
http://lwn.net/Articles/162860/
UPDATE:
The VM_RESERVED flag has been discontinued. See Linus' patch
I'm trying to play around with the local APIC functions in the 2.6.32.40 linux kernel, but I am having some issues. I want to try to send a Non-Maskable Interrupts (NMI) to all of the processors on my system (I am using a Intel i7 Q740). First I read the documentation in Intel's Software Developer's Manual Volume 3 related to the APIC functions. It states that interrupts can be broadcast to all processors through the use of the Interrupt Command Register (ICR) located at address 0xFEE00300. So I wrote a kernel module with the following init function to try to write to this register:
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
MODULE_LICENSE("GPL");
#define SUCCESS 0
#define ICR_ADDRESS 0xFEE00300
#define ICR_PROGRAM 0x000C4C89
static int icr_init(void){
int * ICR = (int *)ICR_ADDRESS;
printk(KERN_ALERT "Programing ICR\n");
*ICR = ICR_PROGRAM;
return SUCCESS;
}
static void icr_exit(void){
printk(KERN_ALERT "Removing ICR Programing module removed");
}
module_init(icr_init);
module_exit(icr_exit);
However, when I insmod this module the kernel crashes and complains about being unable to handle the paging request # address 00000000fee00300. Looking under /proc/iomem I see that this address is in a ranged marked as "reserved"
fee00000-fee00fff : reserved
I've also tried using the functions under :
static inline void __default_local_send_IPI_allbutself(int vector)
but the kernel is still throwing "unable to handle paging request" messages and crashing. Does anyone have any suggestions? Why is this memory range marked as "reserved" and not marked as being used by the local APIC? Thanks in advance.
The APIC address is a physical memory address, but you are trying to access it as a linear memory address - that's why your first approach doesn't work. The memory is marked as "reserved" precisely because it belongs to the APIC, rather than real memory.
You should use the internal kernel functions. To do so, you should include <asm/apic.h> and use:
apic->send_IPI_allbutself(vector);