***************************************************************************** * CREATING A NEW PROC FILE * * * * * * Copyright (c) 2001 Daniel P. Bovet, Marco Cesati, and Cosimo Comella * * Permission is granted to copy, distribute and/or modify this document * * under the terms of the GNU Free Documentation License, Version 1.1, * * published by the Free Software Foundation; with no Invariant Sections, * * with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the * * license is included in the file named LICENSE. * * * * (version 1.1) * ***************************************************************************** The proc file we are going to create contains the current value of four new kernel variables called kdbgvar0, kdbgvar1, kdbgvar2, and kdbgvar3 that can be used for debugging the kernel (for instance, to count how many times a kernel function has been entered). If you type: cat /proc/kdbgvars the current value of these variables will be displayed on the screen. The usual way to implement a new proc file is to modify some existing proc file close to the one we have in mind. In our case, we copy shamelessly from one of the functions in fs/proc/proc_misc.c, namely loadavg_read_proc() ***************************************************************************** STEP 0: set the proper EXTRAVERSION value in Makefile ***************************************************************************** replace: EXTRAVERSION = with: EXTRAVERSION = kh4 ***************************************************************************** STEP 1: add bool CONFIG_KDBGVARS entry in arch/i386/config.in ***************************************************************************** add right after: bool ' Verbose BUG() reporting (adds 70K)' CONFIG_DEBUG_BUGVERBOSE the following line: bool ' Kernel debug variables' CONFIG_KDBGVARS ***************************************************************************** STEP 2: document CONFIG_KDBGVARS in Documentation/Configure.help ***************************************************************************** add right after: Magic System Request Key support CONFIG_MAGIC_SYSRQ If you say Y here, you will have some control over the system even if the system crashes for example during kernel debugging (e.g., you will be able to flush the buffer cache to disk, reboot the system immediately or dump some status information). This is accomplished by pressing various keys while holding SysRq (Alt+PrintScreen). It also works on a serial console (on PC hardware at least), if you send a BREAK and then within 5 seconds a command keypress. The keys are documented in Documentation/sysrq.txt. Don't say Y unless you really know what this hack does. the following lines: Kernel debug variables support CONFIG_KDBGVARS Enabling this option will include in your /proc filesystem a new entry, /proc/kdbgvars, which displays the current values of five new kernel variables denoted as kdbgvar0, ..., kdbgvar3, and kdbgflag. The value of these variables can be set arbitrarily while debugging the kernel. They are displayed in hexadecimal format. ***************************************************************************** STEP 3: create a new directory linux/new_procs that will contain the kdbgvars.c file ***************************************************************************** a) mkdir new_procs ***************************************************************************** STEP 4: modify the main linux/Makefile ***************************************************************************** a) replace: CORE_FILES =kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o with: CORE_FILES =kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o new_procs/new_procs.o b) replace: SUBDIRS =kernel drivers mm fs net ipc lib with: SUBDIRS =kernel drivers mm fs net ipc lib new_procs ***************************************************************************** STEP 5: Add new kernel variables kdbgvar0, ..., kdbgvar3 ***************************************************************************** add in kernel/sched.c file right after: struct kernel_stat kstat; the following lines: #ifdef CONFIG_KDBGVARS unsigned long kdbgvar0 = 0x00000000; unsigned long kdbgvar1 = 0x11111111; unsigned long kdbgvar2 = 0x22222222; unsigned long kdbgvar3 = 0x33333333; #endif ***************************************************************************** STEP 6: Add a new entry in proc_misc_init() ***************************************************************************** a) add in fs/proc/proc_misc.c right after: #ifdef CONFIG_DEBUG_MALLOC extern int get_malloc(char * buffer); #endif the following lines: #ifdef CONFIG_KDBGVARS extern int kdbgvars_read_proc(char *, char **, off_t, int, int *, void *) #endif b) add in fs/proc/proc_misc.c right after: #ifdef CONFIG_SGI_DS1286 {"rtc", ds1286_read_proc}, #endif the following lines: #ifdef CONFIG_KDBGVARS {"kdbgvars", kdbgvars_read_proc}, #endif ***************************************************************************** STEP 7: Create the Makefile for the linux/new_procs directory ***************************************************************************** # # Makefile for linux/new_procs # # Note: dependencies are done automatically by "make dep", which also removes # any old dependency. DON'T put your own dependencies ere unless it's something # special (ie not a .c file). # # Note2: the CFLAGS definition is now in the main Makefile... # O_TARGET := new_procs.o obj-m := obj-y := ifeq ($(CONFIG_KDBGVARS),y) obj-y += kdbgvars_read_proc.o endif include $(TOPDIR)/Rules.make ***************************************************************************** STEP 8: Make proc_calc_metrics visible from other files ***************************************************************************** a) in fs/proc/proc_misc.c replace the lines: static int proc_calc_metrics(char *page, char **start, off_t off, int count, int *eof, int len) with: int proc_calc_metrics(char *page, char **start, off_t off, int count, int *eof, int len) ***************************************************************************** STEP 9: Add a file in the new_procs directory to do the work ***************************************************************************** a) add in the new_procs directory the following file: /* */ /* linux/new_procs/kdbgvars_read_proc.c */ /* */ /* This file contains the function that reads the kdbgvars proc file */ /* */ #include extern int proc_calc_metrics(char *, char **, off_t, int, int *, int); extern unsigned long kdbgvar0, kdbgvar1, kdbgvar2, kdbgvar3; int kdbgvars_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { int len, cc; char *p; p = page; p += sprintf(p, "kdbgvar0= %x, kdbgvar1= %x, kdbgvar2= %x, kdbgvar3= %x\n", kdbgvar0, kdbgvar1, kdbgvar2, kdbgvar3); len = p - page; return proc_calc_metrics(page, start, off, count, eof, len); } ***************************************************************************** STEP 10: Test the new proc file as a static kernel component ***************************************************************************** a) run make menuconfig and set to 'Y' the CONFIG_KDBGVARS kernel hackers option b) recompile the kernel and copy the bzImage in /boot/vmlinuz-2.4.5kh4 or on a floppy c) reboot the system and select linux-2.4.5kh4 as the system to boot d) login and type the following line: cat /proc/kdbgvars e) if everything went right you should get a display like: kdbgvar0= 0, kdbgvar1= 11111111, kdbgvar2= 22222222, kdbgvar3= 33333333