Rumah  >  Artikel  >  Tutorial sistem  >  Fungsi output nyahpepijat dalam kernel Linux: penjelasan terperinci tentang printk

Fungsi output nyahpepijat dalam kernel Linux: penjelasan terperinci tentang printk

PHPz
PHPzke hadapan
2024-02-14 20:33:141239semak imbas

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.

Fungsi output nyahpepijat dalam kernel Linux: penjelasan terperinci tentang printk

1. Pengenalan (berdasarkan s3c2440 linux)

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 */
};

2 Semak konfigurasi tahap melalui arahan cat /proc/sys/kernel/printk:

# 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

3. Ubah suai konfigurasi tahap:

#echo “1 4 1 7”>/proc/sys/kernel/printk Tukar empat nilai ini Apabila console_loglevel ditetapkan kepada 1, semua maklumat penyahpepijatan akan dicetak.

4. Nama dan penggunaan rekod fungsi printk

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

5. Hubungan antara port bersiri dan fungsi printk:

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);
}

konsol uboot=ttySAC0, jika ia dikenali sebagai port bersiri 0 dalam Linux, terdapat kod berikut dalam /kernel/printk.c,

__setup("console=", console_setup);

static int __init console_setup(char *str)
{
........
  add_preferred_console(name, idx, options);
} 

Apabila kernel mula melaksanakan, apabila parameter baris arahan "console=..." ditemui, fungsi console_setup akan dipanggil untuk analisis data Untuk parameter baris arahan "console=ttySAC0", ia akan dihuraikan: the nama peranti (nama) ialah ttySAC, Indeks indeks ialah 0, dan maklumat ini disimpan dalam tatasusunan global jenis console_cmdline dan nama console_cmdline (nota: nama tatasusunan dan jenis tatasusunan adalah sama)

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!

Kenyataan:
Artikel ini dikembalikan pada:lxlinux.net. Jika ada pelanggaran, sila hubungi admin@php.cn Padam