where is the printf source for busybox?
Hi, I've had this question for some time past and I would like to know the answer now.. I wanted to follow a printf in busybox but couldn't find the source of the printf function. Then I throught probably the printf is provided by the system library where printf is connected to proper linux system call. (Is it printk?) So I checkd LD_LIBRARY_PATH of my shell and found libc.so under /lib. I could see by 'nm libc.so' that printf is in the library. But where can I see the printf source? Is it under gcc source? in GNU sdk, under glibc-2.16.0, I tried # grep 'int printf(' * -r but nothing comes up. In linux kernel source doing the same gaves me arch/x86/boot/boot.h:int printf(const char *fmt, ...); arch/x86/boot/printf.c:int printf(const char *fmt, ...) arch/um/include/shared/kern.h:extern int printf(const char *fmt, ...); arch/um/os-Linux/user_syms.c:extern int printf(const char *, ...); arch/powerpc/boot/stdio.h:extern int printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); so printf is defined only for x86 architecture? I understand printf is for user program not kernel, so I want to see how the printf is connected to kernel print function. (the system call, I know in sparc, linux system call is trap 0x90, function 59 when using assembly) Where can I find the printf (user program) source? Thanks in advance. Chan
On Wed, Mar 12, 2014 at 7:14 AM, Kim Chan <ckim@etri.re.kr> wrote:
Hi, I've had this question for some time past and I would like to know the answer now.. I wanted to follow a printf in busybox but couldn't find the source of the printf function. Then I throught probably the printf is provided by the system library where printf is connected to proper linux system call. (Is it printk?) So I checkd LD_LIBRARY_PATH of my shell and found libc.so under /lib. I could see by 'nm libc.so' that printf is in the library. But where can I see the printf source? Is it under gcc source? in GNU sdk, under glibc-2.16.0, I tried # grep 'int printf(' * -r but nothing comes up. In linux kernel source doing the same gaves me arch/x86/boot/boot.h:int printf(const char *fmt, ...); arch/x86/boot/printf.c:int printf(const char *fmt, ...) arch/um/include/shared/kern.h:extern int printf(const char *fmt, ...); arch/um/os-Linux/user_syms.c:extern int printf(const char *, ...); arch/powerpc/boot/stdio.h:extern int printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); so printf is defined only for x86 architecture? I understand printf is for user program not kernel, so I want to see how the printf is connected to kernel print function. (the system call, I know in sparc, linux system call is trap 0x90, function 59 when using assembly) Where can I find the printf (user program) source? Thanks in advance. Chan
Hi Chan, Here is Glibc printf.c code: int __printf (const char *format, ...) { va_list arg; int done; va_start (arg, format); done = vfprintf (stdout, format, arg); va_end (arg); return done; } it in turn call vfprintf. You can see Glibc vfprintf.c (glibc-2.18/stdio-common/vfprintf.c) Correct me If my understanding is wrong. Thanks Mohan L
Hi, Mohan, Thanks! so the printf is name chagned to _printf by the compiler. I missed that. Chan ________________________________ From : "Mohan L" <l.mohanphy@gmail.com> Sent : 2014-03-12 11:07:45 ( +09:00 ) To : Kim Chan <ckim@etri.re.kr> Cc : kernelnewbies@kernelnewbies.org <kernelnewbies@kernelnewbies.org> Subject : Re: where is the printf source for busybox? On Wed, Mar 12, 2014 at 7:14 AM, Kim Chan <ckim@etri.re.kr<mailto:ckim@etri.re.kr>> wrote: Hi, I've had this question for some time past and I would like to know the answer now.. I wanted to follow a printf in busybox but couldn't find the source of the printf function. Then I throught probably the printf is provided by the system library where printf is connected to proper linux system call. (Is it printk?) So I checkd LD_LIBRARY_PATH of my shell and found libc.so under /lib. I could see by 'nm libc.so' that printf is in the library. But where can I see the printf source? Is it under gcc source? in GNU sdk, under glibc-2.16.0, I tried # grep 'int printf(' * -r but nothing comes up. In linux kernel source doing the same gaves me arch/x86/boot/boot.h:int printf(const char *fmt, ...); arch/x86/boot/printf.c:int printf(const char *fmt, ...) arch/um/include/shared/kern.h:extern int printf(const char *fmt, ...); arch/um/os-Linux/user_syms.c:extern int printf(const char *, ...); arch/powerpc/boot/stdio.h:extern int printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); so printf is defined only for x86 architecture? I understand printf is for user program not kernel, so I want to see how the printf is connected to kernel print function. (the system call, I know in sparc, linux system call is trap 0x90, function 59 when using assembly) Where can I find the printf (user program) source? Thanks in advance. Chan Hi Chan, Here is Glibc printf.c code: int __printf (const char *format, ...) { va_list arg; int done; va_start (arg, format); done = vfprintf (stdout, format, arg); va_end (arg); return done; } it in turn call vfprintf. You can see Glibc vfprintf.c (glibc-2.18/stdio-common/vfprintf.c) Correct me If my understanding is wrong. Thanks Mohan L
Hi, On Tue, Mar 11, 2014 at 6:44 PM, Kim Chan <ckim@etri.re.kr> wrote:
Hi, I've had this question for some time past and I would like to know the
answer now..
I wanted to follow a printf in busybox but couldn't find the source of the printf function. Then I throught probably the printf is provided by the system library where printf is connected to proper linux system call. (Is it printk?)
busybox is typically built using uclibc, which is here: http://www.uclibc.org/ The printf source code within uclibc is here: http://git.uclibc.org/uClibc/tree/libc/stdio/printf.c It eveentually winds up in _vfprintf here: http://git.uclibc.org/uClibc/tree/libc/stdio/_vfprintf.c -- Dave Hylands Shuswap, BC, Canada http://www.davehylands.com
On Wed, Mar 12, 2014 at 10:09 AM, Dave Hylands <dhylands@gmail.com> wrote:
Hi,
On Tue, Mar 11, 2014 at 6:44 PM, Kim Chan <ckim@etri.re.kr> wrote:
Hi, I've had this question for some time past and I would like to know the
answer now..
I wanted to follow a printf in busybox but couldn't find the source of the printf function. Then I throught probably the printf is provided by the system library where printf is connected to proper linux system call. (Is it printk?)
busybox is typically built using uclibc, which is here: http://www.uclibc.org/
The printf source code within uclibc is here: http://git.uclibc.org/uClibc/tree/libc/stdio/printf.c
It eveentually winds up in _vfprintf here: http://git.uclibc.org/uClibc/tree/libc/stdio/_vfprintf.c
Hi Dave, I missed busybox. Thanks! Mohan L
Hello Dave, (and Mohan) Thanks for the nice info. I've downloaded uClibc code and ran ctags -R and searched down printf. It looks like the main print path is (assuming __STDIO_BUFFERS : I guess user level buffer for stdin, stdout, stderr) and assuming STDIO_GETC/PUTC_MACRO defined. without the macro, it seems to directly go to __fputc_unlocked..) printf -> vfprintf (very complex doing all the format conversions..) -> PUTC -> putc_unlocked -> __FPUTC_UNLOCKED ->(after some macro conversion) __fputc_unlocked -> __stdio_WRITE (sometime write only to buffer) -> __WRITE -> __gcs.write -> write in libc/stdio/_stdio.h, the __gcs.wirte is assigned to _cs_write and in libc/stdio/_cs_funcs.c, the _cs_write function is defined as below. ssize_t attribute_hidden _cs_write(void *cookie, const char *buf, size_t bufsize) { return write(*((int *) cookie), (char *) buf, bufsize); } what does cs stand for here? (Hm.. seems like custom streams..in the code) and I couldn't follow past write above. Where is the function write defined? Any hint will be deeply appreciated and if I'm wrong with something, please correct me. Thanks and regards, Chan ________________________________ From : "Dave Hylands" <dhylands@gmail.com> Sent : 2014-03-12 13:39:11 ( +09:00 ) To : Kim Chan <ckim@etri.re.kr> Cc : kernelnewbies@kernelnewbies.org <kernelnewbies@kernelnewbies.org> Subject : Re: where is the printf source for busybox? Hi, On Tue, Mar 11, 2014 at 6:44 PM, Kim Chan <ckim@etri.re.kr<mailto:ckim@etri.re.kr>> wrote:
Hi, I've had this question for some time past and I would like to know the answer now.. I wanted to follow a printf in busybox but couldn't find the source of the printf function. Then I throught probably the printf is provided by the system library where printf is connected to proper linux system call. (Is it printk?)
busybox is typically built using uclibc, which is here: http://www.uclibc.org/ The printf source code within uclibc is here: http://git.uclibc.org/uClibc/tree/libc/stdio/printf.c It eveentually winds up in _vfprintf here: http://git.uclibc.org/uClibc/tree/libc/stdio/_vfprintf.c -- Dave Hylands Shuswap, BC, Canada http://www.davehylands.com<http://www.davehylands.com/>
ssize_t attribute_hidden _cs_write(void *cookie, const char *buf, size_t bufsize) { return write(*((int *) cookie), (char *) buf, bufsize); } what does cs stand for here? (Hm.. seems like custom streams..in the code) and I couldn't follow past write above. Where is the function write defined?
Hi Chan, write is a system call. $ man 2 write syscall table for x86 architecture can be found in : <path>/arch/x86/syscalls/syscall_32.tbl # cat <path>/arch/x86/syscalls/syscall_32.tbl | grep 'write' 4 i386 write sys_write The format is: <number> <abi> <name> <entry point> <compat entry point> search sys_write definition in kernel source. Thanks Mohan L
Wow, that was it. I'm happy to hear that because I thought it should end up with a system call anyway. Then isn't there some codes making the system call? Or is it that the compiler understands that 'write' is a system call and inserts the assembly code for calling it by itself? Thanks in adv. Chan ________________________________ From : "Mohan L" <l.mohanphy@gmail.com> Sent : 2014-03-12 15:31:24 ( +09:00 ) To : Kim Chan <ckim@etri.re.kr> Cc : Dave Hylands <dhylands@gmail.com>, kernelnewbies@kernelnewbies.org <kernelnewbies@kernelnewbies.org> Subject : Re: where is the printf source for busybox? ssize_t attribute_hidden _cs_write(void *cookie, const char *buf, size_t bufsize) { return write(*((int *) cookie), (char *) buf, bufsize); } what does cs stand for here? (Hm.. seems like custom streams..in the code) and I couldn't follow past write above. Where is the function write defined? Hi Chan, write is a system call. $ man 2 write syscall table for x86 architecture can be found in : <path>/arch/x86/syscalls/syscall_32.tbl # cat <path>/arch/x86/syscalls/syscall_32.tbl | grep 'write' 4 i386 write sys_write The format is: <number> <abi> <name> <entry point> <compat entry point> search sys_write definition in kernel source. Thanks Mohan L
Hi, On Tue, Mar 11, 2014 at 11:55 PM, Kim Chan <ckim@etri.re.kr> wrote:
Wow, that was it. I'm happy to hear that because I thought it should end up with a system call anyway. Then isn't there some codes making the system call? Or is it that the compiler understands that 'write' is a system call and inserts the assembly code for calling it by itself?
In uclibc, the write source code is found here: http://git.uclibc.org/uClibc/tree/libc/sysdeps/linux/common/write.c How the syscall is actually implemented is architecture specific, and will be in one of the directories here: http://git.uclibc.org/uClibc/tree/libc/sysdeps/linux For example, for ARM, with EABI, then I believe that it winds up here: http://git.uclibc.org/uClibc/tree/libc/sysdeps/linux/arm/syscall-eabi.S The SWI instruction transfers control to the kernel. On the kernel side, how the syscalls get handled is also architecture specific, but it will generally wind up at a function called sys_FUNCTION, however the generation of the function name is usually hidden behind a macro. So sys_write in the kernel winds up being declared here: http://lxr.linux.no/#linux+v3.13.5/fs/read_write.c#L514 -- Dave Hylands Shuswap, BC, Canada http://www.davehylands.com
Hi, Dave, Thank you for the kind explanation and I think it will help much for me. I searched down the uClib as you told me and could locate the kernel sys_write function. In my case, the arch is sparc, and it is defined in fs/read_write.c as you said(in linux kernel source). I've checked that SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, size_t, count) is expanded to => asmlinkage long sys_write(unsigned int fd, const char __user * buf, size_t count) and I was able to use prom_printf (write to uart) to print what I tried to print in busybox with printf. Now I can see busybox printf at least through the uart port though it's not yet shown on the LCD(which I'm trying to map to tty1 and the shell). Thank you! Chan ________________________________ From : "Dave Hylands" <dhylands@gmail.com> Sent : 2014-03-13 02:54:40 ( +09:00 ) To : Kim Chan <ckim@etri.re.kr> Cc : Mohan L <l.mohanphy@gmail.com>, kernelnewbies@kernelnewbies.org <kernelnewbies@kernelnewbies.org> Subject : Re: where is the printf source for busybox? Hi, On Tue, Mar 11, 2014 at 11:55 PM, Kim Chan <ckim@etri.re.kr<mailto:ckim@etri.re.kr>> wrote: Wow, that was it. I'm happy to hear that because I thought it should end up with a system call anyway. Then isn't there some codes making the system call? Or is it that the compiler understands that 'write' is a system call and inserts the assembly code for calling it by itself? In uclibc, the write source code is found here: http://git.uclibc.org/uClibc/tree/libc/sysdeps/linux/common/write.c How the syscall is actually implemented is architecture specific, and will be in one of the directories here: http://git.uclibc.org/uClibc/tree/libc/sysdeps/linux For example, for ARM, with EABI, then I believe that it winds up here: http://git.uclibc.org/uClibc/tree/libc/sysdeps/linux/arm/syscall-eabi.S The SWI instruction transfers control to the kernel. On the kernel side, how the syscalls get handled is also architecture specific, but it will generally wind up at a function called sys_FUNCTION, however the generation of the function name is usually hidden behind a macro. So sys_write in the kernel winds up being declared here: http://lxr.linux.no/#linux+v3.13.5/fs/read_write.c#L514 -- Dave Hylands Shuswap, BC, Canada http://www.davehylands.com<http://www.davehylands.com/>
participants (3)
-
Dave Hylands -
Kim Chan -
Mohan L