We should be looking for the implementation of printf, which is actually available in the linux kernel. I would like to check how to output text since linux covers the interrupt vector table? Check the printk code and find that the original printk is printf. The code is in printk. c01 # printk02asmlinkageint...
We should be looking for the implementation of printf, which is actually available in the linux kernel. I would like to check how to output text since linux covers the interrupt vector table? Check the printk code and find that the original printk is printf. Code in printk. c
01
# Printk
02
Asmlinkage int printk (const char * fmt ,...)
03
{
04
Va_list args;
05
Int r;
06
07
Va_start (args, fmt );
08
R = vprintk (fmt, args );
09
Va_end (args );
10
11
Return r;
12
13
}
001
# Vsprintk
002
Asmlinkage int vprintk (const char * fmt, va_list args)
003
{
004
Int printed_len = 0;
005
Int current_log_level = default_message_loglevel;
006
Unsigned long flags;
007
Int this_cpu;
008
Char * p;
009
010
Boot_delay_msec ();
011
012
Preempt_disable ();
013
/* This stops the holder of console_sem just where we want him */
014
Raw_local_irq_save (flags );
015
This_cpu = smp_processor_id ();
016
017
/*
018
* Ouch, printk recursed into itself!
019
*/
020
If (unlikely (printk_cpu = this_cpu )){
021
/*
022
* If a crash is occurring during printk () on this CPU,
023
* Then try to get the crash message out but make sure
024
* We can't deadlock. Otherwise just return to avoid
025
* Recursion and return-but flag the recursion so that
026
* It can be printed at the next appropriate moment:
027
*/
028
If (! Oops_in_progress ){
029
Recursion_bug = 1;
030
Goto out_restore_irqs;
031
}
032
Zap_locks ();
033
}
034
035
Lockdep_off ();
036
Spin_lock (& logbuf_lock );
037
Printk_cpu = this_cpu;
038
039
If (recursion_bug ){
040
Recursion_bug = 0;
041
Strcpy (printk_buf, recursion_bug_msg );
042
Printed_len = sizeof (recursion_bug_msg );
043
}
044
/* Emit the output into the temporary buffer */
045
Printed_len + = vscnprintf (printk_buf + printed_len,
046
Sizeof (printk_buf)-printed_len, fmt, args );
047
048
049
# Ifdef CONFIG_DEBUG_LL
050
Printascii (printk_buf );
051
# Endif
052
053
/*
054
* Copy the output into log_buf. If the caller didn't provide
055
* Appropriate log level tags, we insert them here
056
*/
057
For (p = printk_buf; * p; p ++ ){
058
If (new_text_line ){
059
/* If a token, set current_log_level and skip over */
060
If (p [0] = '<' & p [1]> = '0' & p [1] <= '7 '&&
061
P [2] = '> '){
062
Current_log_level = p [1]-'0 ';
063
P + = 3;
064
Printed_len-= 3;
065
}
066
067
/* Always output the token */
068
Emit_log_char ('<');
069
Emit_log_char (current_log_level + '0 ');
070
Emit_log_char ('> ');
071
Printed_len + = 3;
072
New_text_line = 0;
073
074
If (printk_time ){
075
/* Follow the token with the time */
076
Char tbuf [50], * tp;
077
Unsigned tlen;
078
Unsigned long t;
079
Unsigned long nanosec_rem;
080
081
T = cpu_clock (printk_cpu );
082
Nanosec_rem = do_div (t, 1000000000 );
083
Tlen = sprintf (tbuf, "[% 5lu. % 06lu]",
084
(Unsigned long) t,
085
Nanosec_rem/1000 );
086
087
For (tp = tbuf; tp <tbuf + tlen; tp ++)
088
Emit_log_char (* tp );
089
Printed_len + = tlen;
090
}
091
092
If (! * P)
093
Break;
094
}
095
096
Emit_log_char (* p );
097
If (* p = '\ n ')
098
New_text_line = 1;
099
}
100
101
/*
102
* Try to acquire and then immediately release
103
* Console semaphore. The release will do all
104
* Actual magic (print out buffers, wake up klogd,
105
* Etc ).
106
*
107
* The acquire_lele_semaphore_for_printk () function
108
* Will release 'logbuf _ lock' regardless of whether it
109
* Actually gets the semaphore or not.
110
*/
111
If (acquire_lele_semaphore_for_printk (this_cpu ))
112
Release_console_sem ();
113
114
Lockdep_on ();
115
Out_restore_irqs:
116
Raw_local_irq_restore (flags );
117
118
Preempt_enable ();
119
Return printed_len;
120
}
Author "[No] left blog"