printk ialah salah satu fungsi penyahpepijatan yang paling biasa digunakan dalam kernel Linux Ia digunakan untuk mengeluarkan maklumat penyahpepijatan kepada penimbal atau konsol kernel, seperti nilai pembolehubah, aliran pelaksanaan fungsi, punca ralat, dsb. Kelebihan printk ialah ia mudah dan mudah digunakan serta tidak memerlukan peralatan atau pemandu tambahan. Pelaksanaan printk melibatkan konsep seperti penampan kernel, tahap log, dan rentetan berformat. Dalam artikel ini, kami akan memperkenalkan prinsip dan kaedah printk, teknologi penyahpepijatan kernel Linux, dan menggambarkan penggunaan dan langkah berjaga-jaganya dengan contoh.
Antara teknologi penyahpepijatan kernel, yang paling mudah ialah penggunaan printk Penggunaannya adalah serupa dengan penggunaan printf dalam aplikasi bahasa C Dalam aplikasi, ia bergantung pada perpustakaan dalam stdio.h, manakala dalam kernel Linux Ada tiada perpustakaan sedemikian, jadi dalam kernel Linux, menggunakan printk ini memerlukan pemahaman tertentu tentang pelaksanaan kernel.
Perbezaan antara printf dan printk: printk akan menambah aksara gaya "" pada permulaan Julat N ialah 0~7, menunjukkan tahap maklumat ini.
Apabila n dalam printk(""......);
Mulakan tahap console_loglevel kepada 7 dalam fail kernel Printk.c (kernel).
/* printk's without a loglevel use this.. */ #define DEFAULT_MESSAGE_LOGLEVEL 4 /* KERN_WARNING */ /* We show everything that is MORE important than this.. */ #define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */ #define DEFAULT_CONSOLE_LOGLEVEL 7 /* anything MORE serious than KERN_DEBUG */int console_printk[4] = { DEFAULT_CONSOLE_LOGLEVEL, /* console_loglevel */ DEFAULT_MESSAGE_LOGLEVEL, /* default_message_loglevel */ MINIMUM_CONSOLE_LOGLEVEL, /* minimum_console_loglevel */ DEFAULT_CONSOLE_LOGLEVEL, /* default_console_loglevel */ };
# kucing /proc/sys/kernel/printk
7 4 1 7
7 4 1 7 antaranya sepadan dengan: console_loglevel, default_message_loglevel, minimum_console_loglevel, default_console_loglevel
#echo “1 4 1 7”>/proc/sys/kernel/printk Tukar empat nilai ini Apabila console_loglevel ditetapkan kepada 1, semua maklumat penyahpepijatan akan dicetak.
Dalam fail kernel: Kernel.h (includelinux), 8 peringkat nama dari 0 hingga 7 ditakrifkan
#define KERN_EMERG "" /* system is unusable */ #define KERN_ALERT "" /* action must be taken immediately */ #define KERN_CRIT "" /* critical conditions */ #define KERN_ERR "" /* error conditions */ #define KERN_WARNING "" /* warning conditions */ #define KERN_NOTICE "" /* normal but significant condition*/ #define KERN_INFO "" /* informational*/ #define KERN_DEBUG "" /* debug-level messages */ #define console_loglevel (console_printk[0]) #define default_message_loglevel (console_printk[1]) #define minimum_console_loglevel (console_printk[2]) #define default_console_loglevel (console_printk[3])
Gunakan printk:
① printk(KERN_WARNING"there is a warning here!\n");//注意,中间没有逗号间隔。 ② printk(KERN_DEBUG"%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
Dalam ① dan ②, kita perlu melihat data dalam buffer log_buf untuk melihat maklumat yang dicetak. Perlu menggunakan arahan #dmesg
#``# dmesg``Linux version 2.6.22.6 (book@book-desktop) (gcc version 3.4.5) #19 Thu Dec 8 14:06:03 CST 2016``CPU: ARM920T [41129200] revision 0 (ARMv4T), cr=c0007177``Machine: SMDK2440``Memory policy: ECC disabled, Data cache writeback``On node 0 totalpages: 16384`` ``DMA zone: 128 pages used ``for` `memmap`` ``DMA zone: 0 pages reserved`` ``DMA zone: 16256 pages, LIFO batch:3`` ``Normal zone: 0 pages used ``for` `memmap``CPU S3C2440A (id 0x32440001)................................
Anda juga boleh menggunakan cat /proc/kmsg& untuk berjalan di latar belakang dan mencetak maklumat penyahpepijatan dalam masa nyata. Dalam ②, __FILE__, FUNCTION dan __LINE__ masing-masing sepadan dengan fail itu, fungsi itu dan baris mana. Sangat praktikal.
# cat /proc/kmsg&``# ./firstdrvtest on``/work/LinuxDrives/20.printk_debug/first_drv.c first_drv_open 23``/work/LinuxDrives/20.printk_debug/first_drv.c first_drv_open 25`` /work/LinuxDrives/20.printk_debug/first_drv.c first_drv_open 27``# ./firstdrvtest off` `/work/LinuxDrives/20.printk_debug/first_drv.c first_drv_open 23``/work/LinuxDrives/ 20.printk_debug/first_drv.c first_drv_open 25``/work/LinuxDrives/20.printk_debug /first_drv.c first_drv_open 27
printk vprintk vscnprintf //先把输出信息放入临时BUFFER // Copy the output into log_buf. // 把临时BUFFER里的数据稍作处理,再写入log_buf // 比如printk("abc")会得到"abc", 再写入log_buf // 可以用dmesg命令把log_buf里的数据打印出来重现内核的输出信息 // 调用硬件的write函数输出 release_console_sem call_console_drivers //从log_buf得到数据,算出打印级别 _call_console_drivers if ((msg_log_level write //con是console_drivers链表中的项,对用具体的输出函 数 在drives/serial/s3c2410.c中查看 在该函数中注册一个console结构体 static void s3c24xx_serial_console_write(struct console *co, const char *s, unsigned int count) { uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar); }
Fungsi output port bersiri akan memanggil fungsi s3c24xx_serial_console_putchar
static int s3c24xx_serial_initconsole(void) { ........................... register_console(&s3c24xx_serial_console); return 0; } static struct console s3c24xx_serial_console = { .name = S3C24XX_SERIAL_NAME,//这个宏被定义为:TTYSAC .device = uart_console_device, //init进程,用户程序打开/dev/console的时候会调用 .flags = CON_PRINTBUFFER,//打印还没有初始化化console前保存在log_buf里面的数据 .index = -1,//选择那个串口,由uboot中的命令决定 .write = s3c24xx_serial_console_write,//控制台输出函数 .setup = s3c24xx_serial_console_setup //串口设置函数 };
Fungsi ini berkaitan dengan perkakasan Ia membaca daftar untuk melihat sama ada data telah dihantar
static void s3c24xx_serial_console_putchar(struct uart_port *port, int ch) { unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON); while (!s3c24xx_serial_console_txrdy(port, ufcon)) barrier(); wr_regb(cons_uart, S3C2410_UTXH, ch); }
__setup("console=", console_setup); static int __init console_setup(char *str) { ........ add_preferred_console(name, idx, options); }
Dalam register_console(&s3c24xx_serial_console) berikut, struktur s3c24xx_serial_console akan dibandingkan dengan peranti dalam tatasusunan console_cmdline.
①Nama yang dihuraikan ialah S3C24XX_SERIAL_NAME, iaitu "ttySAC", dan nama dalam arahan dalam console_cmdline juga ialah "ttySAC"
②Indeks indeks dalam struktur s3c24xx_serial_console ialah -1, yang bermaksud menggunakan indeks dalam parameter baris arahan "console=ttySAC0", indeks = 0
Melalui artikel ini, kami telah mempelajari tentang prinsip dan kaedah printk, teknologi penyahpepijatan kernel Linux, yang boleh digunakan untuk menyahpepijat dan mengeluarkan kernel. Kita harus memilih kaedah yang sesuai berdasarkan keperluan sebenar dan mengikuti beberapa prinsip asas, seperti menggunakan tahap log yang betul, menggunakan rentetan format yang betul, menggunakan fungsi output yang betul, dsb. Printk ialah salah satu fungsi penyahpepijatan yang paling mudah dan berkesan dalam kernel Linux Ia boleh merealisasikan maklum balas dan pemantauan kernel, dan juga boleh meningkatkan kebolehselenggaraan dan kebolehskalaan kernel. Saya harap artikel ini dapat membantu dan memberi inspirasi kepada anda.
Atas ialah kandungan terperinci Fungsi output nyahpepijat dalam kernel Linux: penjelasan terperinci tentang printk. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!