Using Linux kernel version 4.19.291 as the reference base.
ARM Architecture System Call Table
The system call definitions for ARM are located in the source file:
linux-4.19.291/arch/arm/tools/syscall.tbl
File Format Structure Each line in the table represents a specific system call entry with the following syntax:
<id> <abi_type> <call_name> [<handler_func> [<oabi_compat_handler>]]
- : A unique integer identifying the system call number.
- <abi_type>: Specifies the Application Binary Interface scope.
common: Shared between OABI and EABI environments.oabi: Exclusive to the Old ABI.eabi: Exclusive to the Embedded ABI.
- <call_name>: The symbolic name of the system call.
- <handler_func>: The corresponding kernel function that executes the call.
- <oabi_compat_handler>: (Optional) A compatibility wrapper for OABI.
Sample Table Entries:
0 common restart_syscall sys_restart_syscall
1 common exit sys_exit
2 common fork sys_fork
3 common read sys_read
4 common write sys_write
5 common open sys_open
6 common close sys_close
8 common creat sys_creat
9 common link sys_link
Analysis of mmap
The mmap syscall maps files or devices into the process address space. In the table, legacy mappings are often found under OABI.
Table Entry:
90 oabi mmap sys_old_mmap
User-space Prototype:
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
Kernel-space Implementation: The kernel receives arguments via a structure for the old interface:
struct mmap_arg_struct {
unsigned long addr;
unsigned long len;
unsigned long prot;
unsigned long flags;
unsigned long fd;
unsigned long offset;
};
SYSCALL_DEFINE1(old_mmap, struct mmap_arg_struct __user *, arg)
Parameter Breakdown:
- addr: Hint for the start address.
0allows the kernel to pick a suitable location. - len: The size of the mapping.
- prot: Protection flags (e.g., read/write permissions).
- flags: Mapping behavior (e.g., shared vs private).
- fd: File descriptor of the file to map.
- offset: Starting offset within the file.
Protection Flags (prot):
#define PROT_READ 0x1
#define PROT_WRITE 0x2
#define PROT_EXEC 0x4
#define PROT_SEM 0x8
#define PROT_NONE 0x0
#define PROT_GROWSDOWN 0x01000000
#define PROT_GROWSUP 0x02000000
Mapping Flags (flags):
#define MAP_SHARED 0x01
#define MAP_PRIVATE 0x02
#define MAP_SHARED_VALIDATE 0x03
#define MAP_TYPE 0x0f
#define MAP_FIXED 0x10
#define MAP_ANONYMOUS 0x20
#define MAP_GROWSDOWN 0x0100
#define MAP_DENYWRITE 0x0800
#define MAP_EXECUTABLE 0x1000
#define MAP_LOCKED 0x2000
#define MAP_NORESERVE 0x4000
#define MAP_POPULATE 0x8000
#define MAP_NONBLOCK 0x10000
#define MAP_STACK 0x20000
#define MAP_HUGETLB 0x40000
#define MAP_SYNC 0x80000
ABI Differences: OABI vs EABI
Linux on ARM supports two primary ABIs that dictate how system calls are invoked.
OABI (Old ABI) This legacy interface relies on the ARM standard register passing convention (ATPCS). It was predominantly used in ARMv4 and ARMv5 architectures.
EABI (Embedded ABI) This modern standard utilizes the stack-based AAPCS cnovention for passing parameters. It is the standard for ARMv6 and newer architectures.
Key Technical Distinction The fundamental difference lies in parameter passing. OABI passes syscall arguments primarily via registers, whereas EABI passes them via the stack. This structural difference results in binary incompatibility between applications compiled for different ABIs.