Bonus: Plugging _putchar() Into a Custom printf¶
Tools: GCC, Make, strace
Goal¶
Connect a complete, self-contained printf implementation to the operating system by supplying the single function it needs from you.
Background¶
The utils/printf/ directory holds a portable printf implementation, mpaland/printf, designed for embedded systems that have no libc at all.
It knows how to format everything — integers, padding, floats — but it has no idea how to get a character out of the process.
For that it delegates to one hook that you must provide:
The layering is the same idea as the rest of the session, with the formatting done by somebody else's library:
printf() / sprintf() / ...
|
v
_putchar(c) <-- you implement this
|
v
write(1, &c, 1) <-- the write syscall, fd 1 = stdout
|
v
kernel
Your Task¶
Open _putchar.c and fill in the TODO so that the character is written to standard output using write(2):
fd— use 1 for stdout.buf— a pointer to the bytes to write. You have achar, not a pointer; take its address.count— exactly one byte here.
You may use libc's write() directly for this exercise, or your own my_write() from the demo if you would rather keep libc out of it entirely.
Build & Run¶
Check Your Work¶
- Every line should be formatted exactly as the format strings in
main.cask: right-aligned and left-aligned columns should line up, the zero-padded field should carry leading zeros, and the float should show four decimals. Garbled or missing output usually means the address of the wrong thing was passed towrite. -
Look at what actually reaches the kernel:
Count the
writecalls against the number of characters printed. The ratio should tell you something specific about this design; be ready to say what, and how it compares with what libc'sprintfdid in the session 01 demo. -
Nothing in the output path should be libc's stdio. Check that
straceshows no other output-related system call.