顯示具有 linux kernel code 標籤的文章。 顯示所有文章
顯示具有 linux kernel code 標籤的文章。 顯示所有文章

2019年9月4日 星期三

使用 qemu 來做 source code level debug linux kernel - 從 decompress 開始

逍遙山水憶秋年
一般對 linux 使用 qemu + gdb 的除錯方式, 大概都是從 start_kernel 開始, 要是想要從 decompress 開始追起的話, 該怎麼辦呢?

我突然對這有了興趣, 看看怎麼處理。

不過要先來編譯 kernel:

make i386_defconfig
make

首先 decompress 這部份的程式碼在 linux-5.1.15/arch/x86/boot/compressed, 編譯好之後, linux-5.1.15/arch/x86/boot/compressed 也有個 vmlinux, 很可惜, 這個不能拿來當成 debug symbol, 所以幫 linux-5.1.15/arch/x86/boot/compressed/Makefile 加上 -g

KBUILD_CFLAGS := -m$(BITS) -O2 
+KBUILD_CFLAGS := -m$(BITS) -O0 -g

一般我還會把 -O2 改成 -O0, 不知道為什麼, -O2 編譯之後, linux-5.1.15/arch/x86/boot/compressed/vmlinux 會有些 symbol 找不到, 例如: parse_elf, handle_relocations, nm linux-5.1.15/arch/x86/boot/compressed/vmlinux 是看不到他們的。

這樣重新編譯之後, linux-5.1.15/arch/x86/boot/compressed/vmlinux 才能拿來當 debug symbol 並拿來載入 gdb。

使用 qemu 執行 kernel

qemu-system-i386 -kernel arch/x86/boot/bzImage 

啟用 gdb:
qemu-system-i386 -kernel arch/x86/boot/bzImage -S -s

我不知道神奇的 -kernel 是怎麼載入 kernel (似乎是 multiboot 或是特別認出 linux kernel), 不過在我的平台, 可以用 b *0x100000 將 kernel 停在 linux-5.1.15/arch/x86/boot/compressed/head_32.S L64, 你一定很疑惑我是怎麼找到這個位址的吧!

qemu 沒有 bochs 的 magic break point, 所以沒辦法很輕鬆的停在某行程式碼, 我用猜的, 然後在 L65 的地方加入無窮迴圈, 中斷 gdb, 使用 i r eip 查看目前的位址, 很幸運, 就這樣被我找到了。

我不確定這就是 linux kernel 的第一行程式碼進入點, 因為還看到一些其他的程式碼, 但應該是了。

linux-5.1.15/arch/x86/boot/compressed/head_32.S
  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 /*
  3  *  linux/boot/head.S
  4  *
  5  *  Copyright (C) 1991, 1992, 1993  Linus Torvalds
  6  */
  7 
  8 /*
  9  *  head.S contains the 32-bit startup code.
 10  *
 11  * NOTE!!! Startup happens at absolute address 0x00001000, which is also where
 12  * the page directory will exist. The startup code will be overwritten by
 13  * the page directory. [According to comments etc elsewhere on a compressed
 14  * kernel it will end up at 0x1000 + 1Mb I hope so as I assume this. - AC]
 15  *
 16  * Page 0 is deliberately kept safe, since System Management Mode code in
 17  * laptops may need to access the BIOS data stored there.  This is also
 18  * useful for future device drivers that either access the BIOS via VM86
 19  * mode.
 20  */
 21 
 22 /*
 23  * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
 24  */
 25  .text
 26 
 27 #include <linux/init.h>
 28 #include <linux/linkage.h>
 29 #include <asm/segment.h>
 30 #include <asm/page_types.h>
 31 #include <asm/boot.h>
 32 #include <asm/asm-offsets.h>
 33 #include <asm/bootparam.h>
 34 
 35 /*
 36  * The 32-bit x86 assembler in binutils 2.26 will generate R_386_GOT32X
 37  * relocation to get the symbol address in PIC.  When the compressed x86
 38  * kernel isn't built as PIC, the linker optimizes R_386_GOT32X
 39  * relocations to their fixed symbol addresses.  However, when the
 40  * compressed x86 kernel is loaded at a different address, it leads
 41  * to the following load failure:
 42  *
 43  *   Failed to allocate space for phdrs
 44  *
 45  * during the decompression stage.
 46  *
 47  * If the compressed x86 kernel is relocatable at run-time, it should be
 48  * compiled with -fPIE, instead of -fPIC, if possible and should be built as
 49  * Position Independent Executable (PIE) so that linker won't optimize
 50  * R_386_GOT32X relocation to its fixed symbol address.  Older
 51  * linkers generate R_386_32 relocations against locally defined symbols,
 52  * _bss, _ebss, _got and _egot, in PIE.  It isn't wrong, just less
 53  * optimal than R_386_RELATIVE.  But the x86 kernel fails to properly handle
 54  * R_386_32 relocations when relocating the kernel.  To generate
 55  * R_386_RELATIVE relocations, we mark _bss, _ebss, _got and _egot as
 56  * hidden:
 57  */
 58  .hidden _bss
 59  .hidden _ebss
 60  .hidden _got
 61  .hidden _egot
 62 
 63  __HEAD
 64 ENTRY(startup_32)
 65 /* l5: jmp l5 */
 66  cld
 67  /*
 68   * Test KEEP_SEGMENTS flag to see if the bootloader is asking
 69   * us to not reload segments
 70   */
 71  testb $KEEP_SEGMENTS, BP_loadflags(%esi)
 72  jnz 1f
 73 
 74  cli
 75  movl $__BOOT_DS, %eax
 76  movl %eax, %ds
 77  movl %eax, %es
 78  movl %eax, %fs
 79  movl %eax, %gs
 80  movl %eax, %ss
 81 1:
 82 
 83 /*
 84  * Calculate the delta between where we were compiled to run
 85  * at and where we were actually loaded at.  This can only be done
 86  * with a short local call on x86.  Nothing  else will tell us what
 87  * address we are running at.  The reserved chunk of the real-mode
 88  * data at 0x1e4 (defined as a scratch field) are used as the stack
 89  * for this calculation. Only 4 bytes are needed.
 90  */
 91  leal (BP_scratch+4)(%esi), %esp
 92  call 1f
 93 1: popl %ebp
 94  subl $1b, %ebp
 95 
 96 /*
 97  * %ebp contains the address we are loaded at by the boot loader and %ebx
 98  * contains the address where we should move the kernel image temporarily
 99  * for safe in-place decompression.
100  */
101 
102 #ifdef CONFIG_RELOCATABLE
103  movl %ebp, %ebx
104  movl BP_kernel_alignment(%esi), %eax
105  decl %eax
106  addl    %eax, %ebx
107  notl %eax
108  andl    %eax, %ebx
109  cmpl $LOAD_PHYSICAL_ADDR, %ebx
110  jge 1f
111 #endif
112  movl $LOAD_PHYSICAL_ADDR, %ebx
113 1:
114 
115  /* Target address to relocate to for decompression */
116  movl    BP_init_size(%esi), %eax
117  subl    $_end, %eax
118  addl    %eax, %ebx
119 
120  /* Set up the stack */
121  leal boot_stack_end(%ebx), %esp
122 
123  /* Zero EFLAGS */
124  pushl $0
125  popfl
126 
127 /*
128  * Copy the compressed kernel to the end of our buffer
129  * where decompression in place becomes safe.
130  */
131  pushl %esi
132  leal (_bss-4)(%ebp), %esi
133  leal (_bss-4)(%ebx), %edi
134  movl $(_bss - startup_32), %ecx
135  shrl $2, %ecx
136  std
137  rep movsl
138  cld
139  popl %esi
140 
141 /*
142  * Jump to the relocated address.
143  */
144  leal relocated(%ebx), %eax
145  jmp *%eax
146 ENDPROC(startup_32)
147 
148 #ifdef CONFIG_EFI_STUB
149 /*
150  * We don't need the return address, so set up the stack so efi_main() can find
151  * its arguments.
152  */
153 ENTRY(efi_pe_entry)
154 loop:   jmp loop
155  add $0x4, %esp
156 
157  call 1f
158 1: popl %esi
159  subl $1b, %esi
160 
161  popl %ecx
162  movl %ecx, efi32_config(%esi) /* Handle */
163  popl %ecx
164  movl %ecx, efi32_config+8(%esi) /* EFI System table pointer */
165 
166  /* Relocate efi_config->call() */
167  leal efi32_config(%esi), %eax
168  add %esi, 40(%eax)
169  pushl %eax
170 
171  call make_boot_params
172  cmpl $0, %eax
173  je fail
174  movl %esi, BP_code32_start(%eax)
175  popl %ecx
176  pushl %eax
177  pushl %ecx
178  jmp 2f  /* Skip efi_config initialization */
179 ENDPROC(efi_pe_entry)
180 
181 ENTRY(efi32_stub_entry)
182  add $0x4, %esp
183  popl %ecx
184  popl %edx
185 
186  call 1f
187 1: popl %esi
188  subl $1b, %esi
189 
190  movl %ecx, efi32_config(%esi) /* Handle */
191  movl %edx, efi32_config+8(%esi) /* EFI System table pointer */
192 
193  /* Relocate efi_config->call() */
194  leal efi32_config(%esi), %eax
195  add %esi, 40(%eax)
196  pushl %eax
197 2:
198  call efi_main
199  cmpl $0, %eax
200  movl %eax, %esi
201  jne 2f
202 fail:
203  /* EFI init failed, so hang. */
204  hlt
205  jmp fail
206 2:
207  movl BP_code32_start(%esi), %eax
208  leal startup_32(%eax), %eax
209  jmp *%eax
210 ENDPROC(efi32_stub_entry)
211 #endif
212 
213  .text
214 relocated:
215 
216 /*
217  * Clear BSS (stack is currently empty)
218  */
219  xorl %eax, %eax
220  leal _bss(%ebx), %edi
221  leal _ebss(%ebx), %ecx
222  subl %edi, %ecx
223  shrl $2, %ecx
224  rep stosl
225 
226 /*
227  * Adjust our own GOT
228  */
229  leal _got(%ebx), %edx
230  leal _egot(%ebx), %ecx
231 1:
232  cmpl %ecx, %edx
233  jae 2f
234  addl %ebx, (%edx)
235  addl $4, %edx
236  jmp 1b
237 2:
238 
239 /*
240  * Do the extraction, and jump to the new kernel..
241  */
242     /* push arguments for extract_kernel: */
243  pushl $z_output_len /* decompressed length, end of relocs */
244 
245  movl    BP_init_size(%esi), %eax
246  subl    $_end, %eax
247  movl    %ebx, %ebp
248  subl    %eax, %ebp
249  pushl %ebp  /* output address */
250 
251  pushl $z_input_len /* input_len */
252  leal input_data(%ebx), %eax
253  pushl %eax  /* input_data */
254  leal boot_heap(%ebx), %eax
255  pushl %eax  /* heap area */
256  pushl %esi  /* real mode pointer */
257  call extract_kernel /* returns kernel location in %eax */
258  addl $24, %esp
259 
260 /*
261  * Jump to the extracted kernel.
262  */
263  xorl %ebx, %ebx
264  jmp *%eax
265 
266 #ifdef CONFIG_EFI_STUB
267  .data
268 efi32_config:
269  .fill 5,8,0
270  .long efi_call_phys
271  .long 0
272  .byte 0
273 #endif
274 
275 /*
276  * Stack and heap for uncompression
277  */
278  .bss
279  .balign 4
280 boot_heap:
281  .fill BOOT_HEAP_SIZE, 1, 0
282 boot_stack:
283  .fill BOOT_STACK_SIZE, 1, 0
284 boot_stack_end:

head_32.S L144, L145, L213, L214 是跳到 .text relocated 處, 這裡是載入除錯 symbol 的關鍵。

2:
movl BP_code32_start(%esi), %eax
leal startup_32(%eax), %eax
jmp *%eax # 跳到 L214
ENDPROC(efi32_stub_entry)
#endif

.text
relocated:

想辦法得知 %eax 的內容, 其實就是 runtime 的 relocated 位址。

add-symbol-file vmlinux 0x1fa23c4

0x1fa23c4 是在我 qemu 上的值, 這裡就是 .text 的開始, symbol 載入到這位址, 就可以對
linux-5.1.15/arch/x86/boot/compressed/vmlinux 做 source code debug。

list 1 就是我把中斷點設定在
extract_kernel
parse_elf
handle_relocations

startup_32 會在 0x100000, 我從這裡把

movl $LOAD_PHYSICAL_ADDR, %ebx
1:

/* Target address to relocate to for decompression */
movl BP_init_size(%esi), %eax
subl $_end, %eax
addl %eax, %ebx

%ebx 的值印出來。

b *0x100000
b *0x100026
b *0x100078 # linux-5.1.15/arch/x86/boot/compressed/head_32.S L208

list 1. g.sh
1 b *0x100000
2 #b *0x100078
3 add-symbol-file vmlinux 0x1fa23c4
4 b extract_kernel
5 b parse_elf
6 b handle_relocations
7 target remote localhost:1234

gdb -x g.sh



call extract_kernel 之後, L264 就會跳到解開的 kernel - linux-5.1.15/arch/x86/kernel/head_32.S, 從 startup_32 開始執行下去。


b.sh
1  for obj in arch/x86/boot/compressed/head_32.o arch/x86/boot/compressed/misc.o arch/x86/boot/compressed/string.o arch/x86/boot/compressed/cmdline.o arch/x86/boot/compressed/error.o arch/x86/boot/compressed/piggy.o arch/x86/boot/compressed/cpuflags.o arch/x86/boot/compressed/early_serial_console.o arch/x86/boot/compressed/kaslr.o arch/x86/boot/compressed/acpi.o arch/x86/boot/compressed/eboot.o arch/x86/boot/compressed/efi_stub_32.o; do readelf -S $obj | grep -qF .rel.local && { echo "error: $obj has data relocations!" >&2; exit 1; } || true; done; ld -m elf_i386  -pie  --no-dynamic-linker   -T arch/x86/boot/compressed/vmlinux.lds arch/x86/boot/compressed/head_32.o arch/x86/boot/compressed/misc.o arch/x86/boot/compressed/string.o arch/x86/boot/compressed/cmdline.o arch/x86/boot/compressed/error.o arch/x86/boot/compressed/piggy.o arch/x86/boot/compressed/cpuflags.o arch/x86/boot/compressed/early_serial_console.o arch/x86/boot/compressed/kaslr.o arch/x86/boot/compressed/acpi.o arch/x86/boot/compressed/eboot.o arch/x86/boot/compressed/efi_stub_32.o drivers/firmware/efi/libstub/lib.a -o arch/x86/boot/compressed/vmlinux
2   nm arch/x86/boot/compressed/vmlinux | sed -n -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|_end\|_ehead\|_text\|z_.*\)$/#define ZO_\2 0x\1/p' > arch/x86/boot/zoffset.h
3   gcc -Wp,-MD,arch/x86/boot/.header.o.d  -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/8/include -I./arch/x86/include -I./arch/x86/include/generated  -I./include -I./arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I./include/uapi -I./include/generated/uapi -include ./include/linux/kconfig.h -D__KERNEL__ -m16 -g -Os -DDISABLE_BRANCH_PROFILING -Wall -Wstrict-prototypes -march=i386 -mregparm=3 -fno-strict-aliasing -fomit-frame-pointer -fno-pic -mno-mmx -mno-sse -ffreestanding -fno-stack-protector -mpreferred-stack-boundary=2 -D_SETUP -D__ASSEMBLY__ -DSVGA_MODE=NORMAL_VGA -I./arch/x86/boot   -c -o arch/x86/boot/header.o arch/x86/boot/header.S
4   ld -m elf_i386   -m elf_i386 -T arch/x86/boot/setup.ld arch/x86/boot/a20.o arch/x86/boot/bioscall.o arch/x86/boot/cmdline.o arch/x86/boot/copy.o arch/x86/boot/cpu.o arch/x86/boot/cpuflags.o arch/x86/boot/cpucheck.o arch/x86/boot/early_serial_console.o arch/x86/boot/edd.o arch/x86/boot/header.o arch/x86/boot/main.o arch/x86/boot/memory.o arch/x86/boot/pm.o arch/x86/boot/pmjump.o arch/x86/boot/printf.o arch/x86/boot/regs.o arch/x86/boot/string.o arch/x86/boot/tty.o arch/x86/boot/video.o arch/x86/boot/video-mode.o arch/x86/boot/version.o arch/x86/boot/video-vga.o arch/x86/boot/video-vesa.o arch/x86/boot/video-bios.o -o arch/x86/boot/setup.elf
5   objcopy  -O binary arch/x86/boot/setup.elf arch/x86/boot/setup.bin
6   objcopy  -O binary -R .note -R .comment -S arch/x86/boot/compressed/vmlinux arch/x86/boot/vmlinux.bin
7   arch/x86/boot/tools/build arch/x86/boot/setup.bin arch/x86/boot/vmlinux.bin arch/x86/boot/zoffset.h arch/x86/boot/bzImage 

2015年10月25日 星期日

add new system call for arm linux

網路上有很多增加一個 system call for arm linux 的文章, 不過都有些問題, 不是過時了就是那裡怪怪的。

我用 raspberry pi 2 作為平台, linx 4.1.y 為練習的版本, 還蠻新的, 應該可以撐好幾年。

總共要改這些:
modified: arch/arm/include/asm/unistd.h
modified: arch/arm/include/uapi/asm/unistd.h
modified: include/linux/syscalls.h
modified: arch/arm/kernel/Makefile
modified: arch/arm/kernel/calls.S
new file: arch/arm/kernel/my_syscall.c

參考 add_arm_linux_new_syscall.patch, 值得注意的是 L10 從 388 改成 392, 奇怪, 不是才加入一個 system call 到 calls.S 嗎? 怎麼不是 389?? 大栽問?

add_arm_linux_new_syscall.patch
  1 diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
  2 index 32640c4..7cba573 100644
  3 --- a/arch/arm/include/asm/unistd.h
  4 +++ b/arch/arm/include/asm/unistd.h
  5 @@ -19,7 +19,7 @@
  6   * This may need to be greater than __NR_last_syscall+1 in order to
  7   * account for the padding in the syscall table
  8   */
  9 -#define __NR_syscalls  (388)
 10 +#define __NR_syscalls  (392)
 11  
 12  /*
 13   * *NOTE*: This is a ghost syscall private to the kernel.  Only the
 14 diff --git a/arch/arm/include/uapi/asm/unistd.h b/arch/arm/include/uapi/asm/unistd.h
 15 index 0c3f5a0..20031a2 100644
 16 --- a/arch/arm/include/uapi/asm/unistd.h
 17 +++ b/arch/arm/include/uapi/asm/unistd.h
 18 @@ -414,6 +414,7 @@
 19  #define __NR_memfd_create  (__NR_SYSCALL_BASE+385)
 20  #define __NR_bpf   (__NR_SYSCALL_BASE+386)
 21  #define __NR_execveat   (__NR_SYSCALL_BASE+387)
 22 +#define __NR_get_mmu_reg  (__NR_SYSCALL_BASE+388)
 23  
 24  /*
 25   * The following SWIs are ARM private.
 26 diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
 27 index 752725d..c6fc56d 100644
 28 --- a/arch/arm/kernel/Makefile
 29 +++ b/arch/arm/kernel/Makefile
 30 @@ -18,7 +18,7 @@ CFLAGS_REMOVE_return_address.o = -pg
 31  obj-y  := elf.o entry-common.o irq.o opcodes.o \
 32       process.o ptrace.o reboot.o return_address.o \
 33       setup.o signal.o sigreturn_codes.o \
 34 -     stacktrace.o sys_arm.o time.o traps.o
 35 +     stacktrace.o sys_arm.o time.o traps.o my_syscall.o
 36  
 37  obj-$(CONFIG_ATAGS)  += atags_parse.o
 38  obj-$(CONFIG_ATAGS_PROC) += atags_proc.o
 39 diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
 40 index 05745eb..a715f70 100644
 41 --- a/arch/arm/kernel/calls.S
 42 +++ b/arch/arm/kernel/calls.S
 43 @@ -397,6 +397,7 @@
 44  /* 385 */ CALL(sys_memfd_create)
 45    CALL(sys_bpf)
 46    CALL(sys_execveat)
 47 +  CALL(sys_get_mmu_reg)
 48  #ifndef syscalls_counted
 49  .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
 50  #define syscalls_counted
 51 diff --git a/arch/arm/kernel/my_syscall.c b/arch/arm/kernel/my_syscall.c
 52 new file mode 100644
 53 index 0000000..d61144f
 54 --- /dev/null
 55 +++ b/arch/arm/kernel/my_syscall.c
 56 @@ -0,0 +1,87 @@
 57 +#include <linux/linkage.h>
 58 +#include <linux/kernel.h>
 59 +#include <linux/syscalls.h>
 60 +
 61 +
 62 +typedef unsigned int u32;
 63 +
 64 +static void get_ttbr1(u32 *ttbr1)
 65 +{
 66 +  asm
 67 +  (
 68 +    "mrc p15,0,%0,c2,c0,1\n"
 69 +    :"=r"(*ttbr1)
 70 +    :
 71 +    :
 72 +  );
 73 +/*
 74 + * ref: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211h/Bhchbicd.html
 75 +MRC p15, 0, <Rd>, c2, c0, 1            ; Read Translation Table Base Register 1
 76 +MCR p15, 0, <Rd>, c2, c0, 1            ; Write Translation Table Base Register 1 
 77 +*/
 78 +}
 79 +
 80 +static void get_ttbr0(u32 *ttbr0)
 81 +{
 82 +  u32 a;
 83 +  asm
 84 +  (
 85 +    "mrc p15,0,%0,c2,c0,0\n"
 86 +    :"=r"(a)
 87 +    :
 88 +    :
 89 +  );
 90 +  *ttbr0 = a;
 91 +  printk(KERN_ALERT "a: %x\n", a);
 92 +}
 93 +
 94 +
 95 +static void get_ttbcr(u32 *reg)
 96 +{
 97 +  asm
 98 +  (
 99 +    "mrc p15,0,%0,c2,c0,2\n"
100 +    :"=r"(*reg)
101 +    :
102 +    :
103 +  );
104 +
105 +#if 0
106 +http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0211k/Bihgfcgf.html
107 +MRC p15, 0, <Rd>, c2, c0, 2      ; Read Translation Table Base Control Register
108 +MCR p15, 0, <Rd>, c2, c0, 2      ; Write Translation Table Base Control Register
109 +#endif
110 +}
111 +
112 +
113 +SYSCALL_DEFINE1(get_mmu_reg, unsigned int, reg_type)
114 +{
115 +  int reg = 0x12345678;
116 +  printk(KERN_ALERT "reg_type: %x\n", reg_type);
117 +  switch (reg_type)
118 +  {
119 +    case 0:
120 +    {
121 +      get_ttbr0(&reg);
122 +      break;
123 +    }
124 +    case 1:
125 +    {
126 +      get_ttbr1(&reg);
127 +      break;
128 +    }
129 +    case 2:
130 +    {
131 +      get_ttbcr(&reg);
132 +      break;
133 +    }
134 +    default:
135 +    {
136 +      printk(KERN_ALERT "not support reg_type: %x\n", reg_type);
137 +      return -5;
138 +      break;
139 +    }
140 +  }
141 +  return reg;
142 +}
143 +
144 diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
145 index 76d1e38..f1aac22 100644
146 --- a/include/linux/syscalls.h
147 +++ b/include/linux/syscalls.h
148 @@ -701,6 +701,7 @@ asmlinkage long sys_sysfs(int option,
149  asmlinkage long sys_syslog(int type, char __user *buf, int len);
150  asmlinkage long sys_uselib(const char __user *library);
151  asmlinkage long sys_ni_syscall(void);
152 +asmlinkage long sys_get_mmu_reg(unsigned int reg_type);
153  asmlinkage long sys_ptrace(long request, long pid, unsigned long addr,
154        unsigned long data);
155  
156 @@ -825,6 +826,7 @@ asmlinkage long sys_fanotify_mark(int fanotify_fd, unsigned int flags,
157  asmlinkage long sys_syncfs(int fd);
158  
159  asmlinkage long sys_fork(void);
160 +asmlinkage long sys_get_mmu_reg(unsigned int reg_type);
161  asmlinkage long sys_vfork(void);
162  #ifdef CONFIG_CLONE_BACKWARDS
163  asmlinkage long sys_clone(unsigned long, unsigned long, int __user *, int,

如果單純的 +1, compile 很有可能會看到:

arch/arm/kernel/entry-common.S:110: Error: __NR_syscalls is not equal to the size of the syscall table

原因是 arch/arm/kernel/entry-common.S, arch/arm/kernel/calls.S 在計算 a.c L1043~L1045, 沒符合程式邏輯罷了, 解決方法很簡單, 拿到這段檢查程式就好了, 優雅的方法就是去計算其規則, 讓結果符合這個檢查, 392 就是我算出的結果。

cpp.sh L1 是我將 arch/arm/kernel/entry-common.S 展開, L2 是單純的用 as compile, 照著規則算出來看多少才會過關。

這段很難說明, 所以就不說了, a.c L1029 是關鍵, 補上需要的數量, 真的搞不定就拿掉吧!

a.c
 634 
 635  .equ NR_syscalls,0
 636 
 637 # 1 "arch/arm/kernel/calls.S" 1
 638 # 12 "arch/arm/kernel/calls.S"
 639          .equ NR_syscalls,NR_syscalls+1
 640   .equ NR_syscalls,NR_syscalls+1
 641   .equ NR_syscalls,NR_syscalls+1
 642   .equ NR_syscalls,NR_syscalls+1
 643   .equ NR_syscalls,NR_syscalls+1
 644          .equ NR_syscalls,NR_syscalls+1
 645   .equ NR_syscalls,NR_syscalls+1
 646   .equ NR_syscalls,NR_syscalls+1
 647   .equ NR_syscalls,NR_syscalls+1
 648   .equ NR_syscalls,NR_syscalls+1
 649          .equ NR_syscalls,NR_syscalls+1
 650   .equ NR_syscalls,NR_syscalls+1
 651   .equ NR_syscalls,NR_syscalls+1
 652   .equ NR_syscalls,NR_syscalls+1
 653   .equ NR_syscalls,NR_syscalls+1
 654          .equ NR_syscalls,NR_syscalls+1
 655   .equ NR_syscalls,NR_syscalls+1
 656   .equ NR_syscalls,NR_syscalls+1
 657   .equ NR_syscalls,NR_syscalls+1
 658   .equ NR_syscalls,NR_syscalls+1
 659          .equ NR_syscalls,NR_syscalls+1
 660   .equ NR_syscalls,NR_syscalls+1
 661   .equ NR_syscalls,NR_syscalls+1
 662   .equ NR_syscalls,NR_syscalls+1
 663   .equ NR_syscalls,NR_syscalls+1
 664          .equ NR_syscalls,NR_syscalls+1
 665   .equ NR_syscalls,NR_syscalls+1
 666   .equ NR_syscalls,NR_syscalls+1
 667   .equ NR_syscalls,NR_syscalls+1
 668   .equ NR_syscalls,NR_syscalls+1
 669          .equ NR_syscalls,NR_syscalls+1
 670   .equ NR_syscalls,NR_syscalls+1
 671   .equ NR_syscalls,NR_syscalls+1
 672   .equ NR_syscalls,NR_syscalls+1
 673   .equ NR_syscalls,NR_syscalls+1
 674          .equ NR_syscalls,NR_syscalls+1
 675   .equ NR_syscalls,NR_syscalls+1
 676   .equ NR_syscalls,NR_syscalls+1
 677   .equ NR_syscalls,NR_syscalls+1
 678   .equ NR_syscalls,NR_syscalls+1
 679          .equ NR_syscalls,NR_syscalls+1
 680   .equ NR_syscalls,NR_syscalls+1
 681   .equ NR_syscalls,NR_syscalls+1
 682   .equ NR_syscalls,NR_syscalls+1
 683   .equ NR_syscalls,NR_syscalls+1
 684          .equ NR_syscalls,NR_syscalls+1
 685   .equ NR_syscalls,NR_syscalls+1
 686   .equ NR_syscalls,NR_syscalls+1
 687   .equ NR_syscalls,NR_syscalls+1
 688   .equ NR_syscalls,NR_syscalls+1
 689          .equ NR_syscalls,NR_syscalls+1
 690   .equ NR_syscalls,NR_syscalls+1
 691   .equ NR_syscalls,NR_syscalls+1
 692   .equ NR_syscalls,NR_syscalls+1
 693   .equ NR_syscalls,NR_syscalls+1
 694          .equ NR_syscalls,NR_syscalls+1
 695   .equ NR_syscalls,NR_syscalls+1
 696   .equ NR_syscalls,NR_syscalls+1
 697   .equ NR_syscalls,NR_syscalls+1
 698   .equ NR_syscalls,NR_syscalls+1
 699          .equ NR_syscalls,NR_syscalls+1
 700   .equ NR_syscalls,NR_syscalls+1
 701   .equ NR_syscalls,NR_syscalls+1
 702   .equ NR_syscalls,NR_syscalls+1
 703   .equ NR_syscalls,NR_syscalls+1
 704          .equ NR_syscalls,NR_syscalls+1
 705   .equ NR_syscalls,NR_syscalls+1
 706   .equ NR_syscalls,NR_syscalls+1
 707   .equ NR_syscalls,NR_syscalls+1
 708   .equ NR_syscalls,NR_syscalls+1
 709          .equ NR_syscalls,NR_syscalls+1
 710   .equ NR_syscalls,NR_syscalls+1
 711   .equ NR_syscalls,NR_syscalls+1
 712   .equ NR_syscalls,NR_syscalls+1
 713   .equ NR_syscalls,NR_syscalls+1
 714          .equ NR_syscalls,NR_syscalls+1
 715   .equ NR_syscalls,NR_syscalls+1
 716   .equ NR_syscalls,NR_syscalls+1
 717   .equ NR_syscalls,NR_syscalls+1
 718   .equ NR_syscalls,NR_syscalls+1
 719          .equ NR_syscalls,NR_syscalls+1
 720   .equ NR_syscalls,NR_syscalls+1
 721   .equ NR_syscalls,NR_syscalls+1
 722   .equ NR_syscalls,NR_syscalls+1
 723   .equ NR_syscalls,NR_syscalls+1
 724          .equ NR_syscalls,NR_syscalls+1
 725   .equ NR_syscalls,NR_syscalls+1
 726   .equ NR_syscalls,NR_syscalls+1
 727   .equ NR_syscalls,NR_syscalls+1
 728   .equ NR_syscalls,NR_syscalls+1
 729          .equ NR_syscalls,NR_syscalls+1
 730   .equ NR_syscalls,NR_syscalls+1
 731   .equ NR_syscalls,NR_syscalls+1
 732   .equ NR_syscalls,NR_syscalls+1
 733   .equ NR_syscalls,NR_syscalls+1
 734          .equ NR_syscalls,NR_syscalls+1
 735   .equ NR_syscalls,NR_syscalls+1
 736   .equ NR_syscalls,NR_syscalls+1
 737   .equ NR_syscalls,NR_syscalls+1
 738   .equ NR_syscalls,NR_syscalls+1
 739           .equ NR_syscalls,NR_syscalls+1
 740   .equ NR_syscalls,NR_syscalls+1
 741   .equ NR_syscalls,NR_syscalls+1
 742   .equ NR_syscalls,NR_syscalls+1
 743   .equ NR_syscalls,NR_syscalls+1
 744           .equ NR_syscalls,NR_syscalls+1
 745   .equ NR_syscalls,NR_syscalls+1
 746   .equ NR_syscalls,NR_syscalls+1
 747   .equ NR_syscalls,NR_syscalls+1
 748   .equ NR_syscalls,NR_syscalls+1
 749           .equ NR_syscalls,NR_syscalls+1
 750   .equ NR_syscalls,NR_syscalls+1
 751   .equ NR_syscalls,NR_syscalls+1
 752   .equ NR_syscalls,NR_syscalls+1
 753   .equ NR_syscalls,NR_syscalls+1
 754           .equ NR_syscalls,NR_syscalls+1
 755   .equ NR_syscalls,NR_syscalls+1
 756   .equ NR_syscalls,NR_syscalls+1
 757   .equ NR_syscalls,NR_syscalls+1
 758   .equ NR_syscalls,NR_syscalls+1
 759           .equ NR_syscalls,NR_syscalls+1
 760   .equ NR_syscalls,NR_syscalls+1
 761   .equ NR_syscalls,NR_syscalls+1
 762   .equ NR_syscalls,NR_syscalls+1
 763   .equ NR_syscalls,NR_syscalls+1
 764           .equ NR_syscalls,NR_syscalls+1
 765   .equ NR_syscalls,NR_syscalls+1
 766   .equ NR_syscalls,NR_syscalls+1
 767   .equ NR_syscalls,NR_syscalls+1
 768   .equ NR_syscalls,NR_syscalls+1
 769           .equ NR_syscalls,NR_syscalls+1
 770   .equ NR_syscalls,NR_syscalls+1
 771   .equ NR_syscalls,NR_syscalls+1
 772   .equ NR_syscalls,NR_syscalls+1
 773   .equ NR_syscalls,NR_syscalls+1
 774           .equ NR_syscalls,NR_syscalls+1
 775   .equ NR_syscalls,NR_syscalls+1
 776   .equ NR_syscalls,NR_syscalls+1
 777   .equ NR_syscalls,NR_syscalls+1
 778   .equ NR_syscalls,NR_syscalls+1
 779           .equ NR_syscalls,NR_syscalls+1
 780   .equ NR_syscalls,NR_syscalls+1
 781   .equ NR_syscalls,NR_syscalls+1
 782   .equ NR_syscalls,NR_syscalls+1
 783   .equ NR_syscalls,NR_syscalls+1
 784           .equ NR_syscalls,NR_syscalls+1
 785   .equ NR_syscalls,NR_syscalls+1
 786   .equ NR_syscalls,NR_syscalls+1
 787   .equ NR_syscalls,NR_syscalls+1
 788   .equ NR_syscalls,NR_syscalls+1
 789           .equ NR_syscalls,NR_syscalls+1
 790   .equ NR_syscalls,NR_syscalls+1
 791   .equ NR_syscalls,NR_syscalls+1
 792   .equ NR_syscalls,NR_syscalls+1
 793   .equ NR_syscalls,NR_syscalls+1
 794           .equ NR_syscalls,NR_syscalls+1
 795   .equ NR_syscalls,NR_syscalls+1
 796   .equ NR_syscalls,NR_syscalls+1
 797   .equ NR_syscalls,NR_syscalls+1
 798   .equ NR_syscalls,NR_syscalls+1
 799           .equ NR_syscalls,NR_syscalls+1
 800   .equ NR_syscalls,NR_syscalls+1
 801   .equ NR_syscalls,NR_syscalls+1
 802   .equ NR_syscalls,NR_syscalls+1
 803   .equ NR_syscalls,NR_syscalls+1
 804           .equ NR_syscalls,NR_syscalls+1
 805   .equ NR_syscalls,NR_syscalls+1
 806   .equ NR_syscalls,NR_syscalls+1
 807   .equ NR_syscalls,NR_syscalls+1
 808   .equ NR_syscalls,NR_syscalls+1
 809           .equ NR_syscalls,NR_syscalls+1
 810   .equ NR_syscalls,NR_syscalls+1
 811   .equ NR_syscalls,NR_syscalls+1
 812   .equ NR_syscalls,NR_syscalls+1
 813   .equ NR_syscalls,NR_syscalls+1
 814           .equ NR_syscalls,NR_syscalls+1
 815   .equ NR_syscalls,NR_syscalls+1
 816   .equ NR_syscalls,NR_syscalls+1
 817   .equ NR_syscalls,NR_syscalls+1
 818   .equ NR_syscalls,NR_syscalls+1
 819           .equ NR_syscalls,NR_syscalls+1
 820   .equ NR_syscalls,NR_syscalls+1
 821   .equ NR_syscalls,NR_syscalls+1
 822   .equ NR_syscalls,NR_syscalls+1
 823   .equ NR_syscalls,NR_syscalls+1
 824           .equ NR_syscalls,NR_syscalls+1
 825   .equ NR_syscalls,NR_syscalls+1
 826   .equ NR_syscalls,NR_syscalls+1
 827   .equ NR_syscalls,NR_syscalls+1
 828   .equ NR_syscalls,NR_syscalls+1
 829           .equ NR_syscalls,NR_syscalls+1
 830   .equ NR_syscalls,NR_syscalls+1
 831   .equ NR_syscalls,NR_syscalls+1
 832   .equ NR_syscalls,NR_syscalls+1
 833   .equ NR_syscalls,NR_syscalls+1
 834           .equ NR_syscalls,NR_syscalls+1
 835   .equ NR_syscalls,NR_syscalls+1
 836   .equ NR_syscalls,NR_syscalls+1
 837   .equ NR_syscalls,NR_syscalls+1
 838   .equ NR_syscalls,NR_syscalls+1
 839           .equ NR_syscalls,NR_syscalls+1
 840   .equ NR_syscalls,NR_syscalls+1
 841   .equ NR_syscalls,NR_syscalls+1
 842   .equ NR_syscalls,NR_syscalls+1
 843   .equ NR_syscalls,NR_syscalls+1
 844           .equ NR_syscalls,NR_syscalls+1
 845   .equ NR_syscalls,NR_syscalls+1
 846   .equ NR_syscalls,NR_syscalls+1
 847   .equ NR_syscalls,NR_syscalls+1
 848   .equ NR_syscalls,NR_syscalls+1
 849           .equ NR_syscalls,NR_syscalls+1
 850   .equ NR_syscalls,NR_syscalls+1
 851   .equ NR_syscalls,NR_syscalls+1
 852   .equ NR_syscalls,NR_syscalls+1
 853   .equ NR_syscalls,NR_syscalls+1
 854           .equ NR_syscalls,NR_syscalls+1
 855   .equ NR_syscalls,NR_syscalls+1
 856   .equ NR_syscalls,NR_syscalls+1
 857   .equ NR_syscalls,NR_syscalls+1
 858   .equ NR_syscalls,NR_syscalls+1
 859           .equ NR_syscalls,NR_syscalls+1
 860   .equ NR_syscalls,NR_syscalls+1
 861   .equ NR_syscalls,NR_syscalls+1
 862   .equ NR_syscalls,NR_syscalls+1
 863   .equ NR_syscalls,NR_syscalls+1
 864           .equ NR_syscalls,NR_syscalls+1
 865   .equ NR_syscalls,NR_syscalls+1
 866   .equ NR_syscalls,NR_syscalls+1
 867   .equ NR_syscalls,NR_syscalls+1
 868   .equ NR_syscalls,NR_syscalls+1
 869           .equ NR_syscalls,NR_syscalls+1
 870   .equ NR_syscalls,NR_syscalls+1
 871   .equ NR_syscalls,NR_syscalls+1
 872   .equ NR_syscalls,NR_syscalls+1
 873   .equ NR_syscalls,NR_syscalls+1
 874           .equ NR_syscalls,NR_syscalls+1
 875   .equ NR_syscalls,NR_syscalls+1
 876   .equ NR_syscalls,NR_syscalls+1
 877   .equ NR_syscalls,NR_syscalls+1
 878   .equ NR_syscalls,NR_syscalls+1
 879           .equ NR_syscalls,NR_syscalls+1
 880   .equ NR_syscalls,NR_syscalls+1
 881   .equ NR_syscalls,NR_syscalls+1
 882   .equ NR_syscalls,NR_syscalls+1
 883   .equ NR_syscalls,NR_syscalls+1
 884           .equ NR_syscalls,NR_syscalls+1
 885   .equ NR_syscalls,NR_syscalls+1
 886   .equ NR_syscalls,NR_syscalls+1
 887   .equ NR_syscalls,NR_syscalls+1
 888   .equ NR_syscalls,NR_syscalls+1
 889           .equ NR_syscalls,NR_syscalls+1
 890   .equ NR_syscalls,NR_syscalls+1
 891   .equ NR_syscalls,NR_syscalls+1
 892   .equ NR_syscalls,NR_syscalls+1
 893   .equ NR_syscalls,NR_syscalls+1
 894           .equ NR_syscalls,NR_syscalls+1
 895   .equ NR_syscalls,NR_syscalls+1
 896   .equ NR_syscalls,NR_syscalls+1
 897   .equ NR_syscalls,NR_syscalls+1
 898   .equ NR_syscalls,NR_syscalls+1
 899           .equ NR_syscalls,NR_syscalls+1
 900   .equ NR_syscalls,NR_syscalls+1
 901   .equ NR_syscalls,NR_syscalls+1
 902   .equ NR_syscalls,NR_syscalls+1
 903   .equ NR_syscalls,NR_syscalls+1
 904           .equ NR_syscalls,NR_syscalls+1
 905   .equ NR_syscalls,NR_syscalls+1
 906   .equ NR_syscalls,NR_syscalls+1
 907   .equ NR_syscalls,NR_syscalls+1
 908   .equ NR_syscalls,NR_syscalls+1
 909           .equ NR_syscalls,NR_syscalls+1
 910   .equ NR_syscalls,NR_syscalls+1
 911   .equ NR_syscalls,NR_syscalls+1
 912   .equ NR_syscalls,NR_syscalls+1
 913   .equ NR_syscalls,NR_syscalls+1
 914           .equ NR_syscalls,NR_syscalls+1
 915   .equ NR_syscalls,NR_syscalls+1
 916   .equ NR_syscalls,NR_syscalls+1
 917   .equ NR_syscalls,NR_syscalls+1
 918   .equ NR_syscalls,NR_syscalls+1
 919           .equ NR_syscalls,NR_syscalls+1
 920   .equ NR_syscalls,NR_syscalls+1
 921   .equ NR_syscalls,NR_syscalls+1
 922   .equ NR_syscalls,NR_syscalls+1
 923   .equ NR_syscalls,NR_syscalls+1
 924           .equ NR_syscalls,NR_syscalls+1
 925   .equ NR_syscalls,NR_syscalls+1
 926   .equ NR_syscalls,NR_syscalls+1
 927   .equ NR_syscalls,NR_syscalls+1
 928   .equ NR_syscalls,NR_syscalls+1
 929           .equ NR_syscalls,NR_syscalls+1
 930   .equ NR_syscalls,NR_syscalls+1
 931   .equ NR_syscalls,NR_syscalls+1
 932   .equ NR_syscalls,NR_syscalls+1
 933   .equ NR_syscalls,NR_syscalls+1
 934           .equ NR_syscalls,NR_syscalls+1
 935   .equ NR_syscalls,NR_syscalls+1
 936   .equ NR_syscalls,NR_syscalls+1
 937   .equ NR_syscalls,NR_syscalls+1
 938   .equ NR_syscalls,NR_syscalls+1
 939           .equ NR_syscalls,NR_syscalls+1
 940   .equ NR_syscalls,NR_syscalls+1
 941   .equ NR_syscalls,NR_syscalls+1
 942   .equ NR_syscalls,NR_syscalls+1
 943   .equ NR_syscalls,NR_syscalls+1
 944           .equ NR_syscalls,NR_syscalls+1
 945   .equ NR_syscalls,NR_syscalls+1
 946   .equ NR_syscalls,NR_syscalls+1
 947   .equ NR_syscalls,NR_syscalls+1
 948   .equ NR_syscalls,NR_syscalls+1
 949           .equ NR_syscalls,NR_syscalls+1
 950   .equ NR_syscalls,NR_syscalls+1
 951   .equ NR_syscalls,NR_syscalls+1
 952               .equ NR_syscalls,NR_syscalls+1
 953   .equ NR_syscalls,NR_syscalls+1
 954           .equ NR_syscalls,NR_syscalls+1
 955   .equ NR_syscalls,NR_syscalls+1
 956   .equ NR_syscalls,NR_syscalls+1
 957   .equ NR_syscalls,NR_syscalls+1
 958   .equ NR_syscalls,NR_syscalls+1
 959           .equ NR_syscalls,NR_syscalls+1
 960   .equ NR_syscalls,NR_syscalls+1
 961   .equ NR_syscalls,NR_syscalls+1
 962   .equ NR_syscalls,NR_syscalls+1
 963   .equ NR_syscalls,NR_syscalls+1
 964           .equ NR_syscalls,NR_syscalls+1
 965   .equ NR_syscalls,NR_syscalls+1
 966   .equ NR_syscalls,NR_syscalls+1
 967   .equ NR_syscalls,NR_syscalls+1
 968   .equ NR_syscalls,NR_syscalls+1
 969           .equ NR_syscalls,NR_syscalls+1
 970   .equ NR_syscalls,NR_syscalls+1
 971   .equ NR_syscalls,NR_syscalls+1
 972   .equ NR_syscalls,NR_syscalls+1
 973   .equ NR_syscalls,NR_syscalls+1
 974           .equ NR_syscalls,NR_syscalls+1
 975   .equ NR_syscalls,NR_syscalls+1
 976   .equ NR_syscalls,NR_syscalls+1
 977   .equ NR_syscalls,NR_syscalls+1
 978   .equ NR_syscalls,NR_syscalls+1
 979           .equ NR_syscalls,NR_syscalls+1
 980   .equ NR_syscalls,NR_syscalls+1
 981   .equ NR_syscalls,NR_syscalls+1
 982   .equ NR_syscalls,NR_syscalls+1
 983   .equ NR_syscalls,NR_syscalls+1
 984           .equ NR_syscalls,NR_syscalls+1
 985   .equ NR_syscalls,NR_syscalls+1
 986   .equ NR_syscalls,NR_syscalls+1
 987   .equ NR_syscalls,NR_syscalls+1
 988   .equ NR_syscalls,NR_syscalls+1
 989           .equ NR_syscalls,NR_syscalls+1
 990   .equ NR_syscalls,NR_syscalls+1
 991   .equ NR_syscalls,NR_syscalls+1
 992   .equ NR_syscalls,NR_syscalls+1
 993   .equ NR_syscalls,NR_syscalls+1
 994           .equ NR_syscalls,NR_syscalls+1
 995   .equ NR_syscalls,NR_syscalls+1
 996   .equ NR_syscalls,NR_syscalls+1
 997   .equ NR_syscalls,NR_syscalls+1
 998   .equ NR_syscalls,NR_syscalls+1
 999           .equ NR_syscalls,NR_syscalls+1
1000   .equ NR_syscalls,NR_syscalls+1
1001   .equ NR_syscalls,NR_syscalls+1
1002   .equ NR_syscalls,NR_syscalls+1
1003   .equ NR_syscalls,NR_syscalls+1
1004           .equ NR_syscalls,NR_syscalls+1
1005   .equ NR_syscalls,NR_syscalls+1
1006   .equ NR_syscalls,NR_syscalls+1
1007   .equ NR_syscalls,NR_syscalls+1
1008   .equ NR_syscalls,NR_syscalls+1
1009           .equ NR_syscalls,NR_syscalls+1
1010   .equ NR_syscalls,NR_syscalls+1
1011   .equ NR_syscalls,NR_syscalls+1
1012   .equ NR_syscalls,NR_syscalls+1
1013   .equ NR_syscalls,NR_syscalls+1
1014           .equ NR_syscalls,NR_syscalls+1
1015   .equ NR_syscalls,NR_syscalls+1
1016   .equ NR_syscalls,NR_syscalls+1
1017   .equ NR_syscalls,NR_syscalls+1
1018   .equ NR_syscalls,NR_syscalls+1
1019           .equ NR_syscalls,NR_syscalls+1
1020   .equ NR_syscalls,NR_syscalls+1
1021   .equ NR_syscalls,NR_syscalls+1
1022   .equ NR_syscalls,NR_syscalls+1
1023   .equ NR_syscalls,NR_syscalls+1
1024           .equ NR_syscalls,NR_syscalls+1
1025   .equ NR_syscalls,NR_syscalls+1
1026   .equ NR_syscalls,NR_syscalls+1
1027   .equ NR_syscalls,NR_syscalls+1
1028 
1029 .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
1030 
1031 
1032 .rept syscalls_padding
1033   .equ NR_syscalls,NR_syscalls+1
1034 .endr
1035 # 102 "arch/arm/kernel/entry-common.S" 2
1036 
1042 
1043 .ifne NR_syscalls - (388)
1044 .error "__NR_syscalls is not equal to the size of the syscall table"
1045 .endif
1046 # 122 "arch/arm/kernel/entry-common.S"
1047  .align 5
1048 .globl vector_swi ; .align 0 ; vector_swi:
1049 

cpp.sh
1 arm-linux-gnueabihf-gcc -Wp,-MD,arch/arm/kernel/.entry-common.o.d  -nostdinc -isystem /media/work/altera/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin/../lib/gcc/arm-linux-gnueabihf/4.9.2/include -I./arch/arm/include -Iarch/arm/include/generated/uapi -Iarch/arm/include/generated  -Iinclude -I./arch/arm/include/uapi -Iarch/arm/include/generated/uapi -I./include/uapi -Iinclude/generated/uapi -include ./include/linux/kconfig.h -D__KERNEL__ -mlittle-endian -Iarch/arm/mach-bcm2709/include   -D__ASSEMBLY__ -mabi=aapcs-linux -mno-thumb-interwork -mfpu=vfp -funwind-tables -marm -D__LINUX_ARM_ARCH__=7 -march=armv7-a  -include asm/unified.h -msoft-float  -DCC_HAVE_ASM_GOTO            -E arch/arm/kernel/entry-common.S > /tmp/a.c

2 arm-linux-gnueabihf-as -c /tmp/a.c
3 arch/arm/kernel/entry-common.S: Assembler messages:
4 arch/arm/kernel/entry-common.S:110: Error: __NR_syscalls is not equal to the size of the syscall table

add_arm_linux_new_syscall.patch L113 我用了可以傳入一個參數的 macro, 可以參考其它的 system call 看看如何使用不同參數的版本, ex: SYSCALL_DEFINE3。system call 並不是表面上看的那麼單純, 我認為只有實作過才真的能理解它, 否則你只是停留在理論的理解。

test_my_syscall.c 用來呼叫這個 new system call, 這是把 mmu ttbr0 印出來, 我本來想解開 linux mmu 位址轉換的祕密, 很可惜失敗了。

test_my_syscall.c
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 #include <errno.h>
 5 typedef unsigned int u32;
 6 
 7 int my_syscall(int reg_type)
 8 {     
 9   printf("user mode ## reg_type : %d\n", reg_type);
10   return (long) syscall(388, reg_type);
11 } 
12 
13 int main(int argc, char *argv[])
14 {
15   int reg_type=0;
16 
17   if (argc >= 2)
18     reg_type = strtol(argv[1], NULL, 10);
19 
20   printf("page size: %d\n", getpagesize());
21 
22   u32 ttbr0 = my_syscall(reg_type);
23   if (ttbr0 == -1)
24   {
25     perror("err");
26   }
27   printf("reg: %x\n", ttbr0);
28   return 0;
29 }