Re: Help: interactive REPL I/O for user program on L4 Re/Fiasco.OC (amd64-plain) — Vcon/cons nearly worki ng; canonical approach?

"R.A. James" <[email protected]> Sun, 7 Sep 2025 08:09:03 -0400
Newsgroups gmane.comp.micro-kernel.l4.devel
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--===============0324897902204933820==
Content-Type: multipart/alternative;
 boundary="------------3Uuv5snkeSjfo1H4UJhWG0a4"
Content-Language: en-US

This is a multi-part message in MIME format.
--------------3Uuv5snkeSjfo1H4UJhWG0a4
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit

I found my solution yesterday! Thanks & I'll share.

-- -- quark.cfg — Start cons and give StarForth its own NEW Vcon 
(stdin+stdout) -- local L4 =rawget(_G, "L4") or require("L4") local l =L4.default_loader -- 1) cons session factory local cons_mux =l:new_channel() -- 2) start cons (frontend is parent's serial; 
auto-connect "starforth") l :start({ caps = { cons = cons_mux:svr(), -- publish cons factory fe = 
L4.Env.log, -- cons frontend (serial/stdio) }, }, "rom/cons -m l4re -f 
fe -a -c starforth") -- If your cons expects 'log' instead of 'fe', use 
this instead :
-- l :start({ -- caps ={ cons = cons_mux:svr(), log = L4.Env.log }, -- }, "rom/cons -m l4re -f 
log -a -c starforth") -- 3) tell loader to obtain log objects from cons 
(not the write-only logger) l.log_fab =cons_mux -- 4) start StarForth; loader asks cons to CREATE a NEW Vcon 
named 'starforth' l :start({ log = { "starforth", "yellow", "key=1", "show" }, }, 
"rom/starforth")



On 9/3/25 15:03, Robert A. James wrote:
>
> Hello l4-hackers,
>
> My name is Robert (Bob) A. James I'm VERY new to the L4Re world. This 
> is also my first foray into systems programming having come from the 
> Medical Device and Enterprise areas during my career. I am now retired 
> and developing a full Operating System based on L4Re/Fiasco.OC.
>
> I’m looking for guidance on the /canonical/ way to wire an interactive 
> text console (stdin/stdout) for a user program under L4Re/Fiasco.OC on 
> amd64-plain.
>
> Context
>
>  *
>
>     I have a small, headless FORTH VM (“StarForth”) running under
>     L4Re/Fiasco.OC; its self-tests pass. What’s missing is an
>     *interactive REPL*.
>
>  *
>
>     Target outcomes:
>     a) Run via |make qemu E=starforth O=build-x86_64|
>     b) Build GRUB2 ISO via |make grub2iso E=starforth O=build-x86_64|
>     c) ISO runs in QEMU and VirtualBox
>     d) Same ISO boots on commodity x86_64 hardware
>
> What I’ve tried (and where I’m stuck)
>
> 1.
>
>     *Vcon + cons* (almost there)
>
>      *
>
>         My mental model: Vcon as a frontend; |cons| providing the
>         console service; StarForth as the “backend” client/subscriber.
>
>      *
>
>         Behavior I see:
>         • The “terminal” prints what the *logger* prints rather than
>         the process’s normal *stdout*.
>         • Output sometimes *flushes only on newline*; interactive
>         prompts without |\n| don’t appear reliably.
>
>      *
>
>         Aside from those two issues, this was close to a working REPL.
>
>      *
>
>         *Questions:* Is |cons| effectively write-only (log)? If so,
>         what’s the supported input-capable console frontend to bind
>         both stdin and stdout for a user process? Is there a minimal
>         example showing correct capability wiring so user
>         stdout/stderr don’t get mixed with the system log?
>
> 2.
>
>     *GOOS/Framebuffer route*
>
>      *
>
>         I attempted a tiny terminal server that maps the GOOS
>         framebuffer and renders an 8×16 CP437 font. I did not get this
>         path working end-to-end, so I’m fine dropping it if there’s a
>         simpler, recommended console approach.
>
> What would help
>
>  *
>
>     The *recommended minimal pattern* (modules/services + boot script)
>     to give a user task a real interactive stdin/stdout:
>
>      o
>
>         works with |make qemu …| and |make grub2iso …|
>
>      o
>
>         also works on typical PCs without a full graphics stack.
>
>  *
>
>     A *small reference* that: (1) prints text, and (2) reads
>     keystrokes from the user, with a snippet of |modules.list| and the
>     Lua loader snippet.
>
> Environment / details
>
>  *
>
>     L4Re/Fiasco.OC on amd64-plain, built with the L4Re toolchain.
>
>  *
>
>     Intended entry points: |make qemu E=starforth O=build-x86_64|,
>     |make grub2iso E=starforth O=build-x86_64|.
>
> One of my simple boot variants (for reference):
>
> |modules.list| (simplified)
>
> entry starforth
> kernel fiasco -serial_esc
> roottask moe rom/quark.cfg
> module l4re
> module ned
> module cons
> module quark.cfg
> module starforth
> |quark.cfg| --> I think this is about what I had.
> -- rom/quark.cfg local L4 =require("L4") local ld =L4.default_loader -- Start cons; feed it to the real serial logger (fe =L4.Env.log) local cons_ctl =ld:new_channel() ld:start({ caps = { cons = cons_ctl:svr(), -- server gate for cons' 
> factory fe = L4.Env.log, -- cons frontend goes to serial/log }, }, 
> "rom/cons -m l4re -f fe -a -t -c StarForth") -- ← added -c StarForth 
> -- Ask cons to create a Vcon client for StarForth and pass it in as 
> 'tty' -- (Capabilities are first-class in Ned; calling 'create' on 
> caps is supported.) local tty =cons_ctl:create(L4.Proto.Log, "StarForth", "show", "key=1", 
> "bufsz=65536") -- Start StarForth with that Vcon as its TTY ld:start({ caps = { tty = tty, -- the Vcon client for StarForth }, }, 
> "rom/starforth")
> I can share a minimal reproducible case (sources, build logs, QEMU 
> output) off-list if that helps.
>
> Thanks in advance for any pointers to the “right way,” or to a 
> maintained example I can follow.
>
> Best regards,
> R. A. “Bob” James ([email protected])
>
> Kubuntu 25.04 • amd64-plain • QEMU/VirtualBox • GRUB2 boot targets
>
>
> _______________________________________________
> l4-hackers mailing list [email protected]
> To unsubscribe send an email [email protected]
--------------3Uuv5snkeSjfo1H4UJhWG0a4
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 8bit

<!DOCTYPE html>
<html data-lt-installed="true">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body style="padding-bottom: 1px;">
    <p>I found my solution yesterday! Thanks &amp; I'll share.<br>
      <br>
    </p>
    <div style="background-color:#131314;color:#ebebeb">
      <pre
      style="font-family:'JetBrains Mono',monospace;font-size:9.8pt;"><span
      style="color:#ffffff;">--
</span><span style="color:#ffffff;">-- quark.cfg — Start cons and give StarForth its own NEW Vcon (stdin+stdout)
</span><span style="color:#ffffff;">--
</span><span style="color:#ffffff;">
</span><span style="color:#ffffff;">local L4 </span>= <span
      style="color:#54b33e;">rawget(_G, "L4") or require("L4")
</span><span style="color:#ffffff;">local l </span>= <span
      style="color:#54b33e;">L4.default_loader
</span><span style="color:#54b33e;">
</span><span style="color:#ffffff;">-- 1) cons session factory
</span><span style="color:#ffffff;">local cons_mux </span>= <span
      style="color:#54b33e;">l:new_channel()
</span><span style="color:#54b33e;">
</span><span style="color:#ffffff;">-- 2) start cons (frontend is parent's serial; auto-connect "starforth")
</span><span style="color:#ffffff;">l </span>: <span
      style="color:#54b33e;">start({
</span><span style="color:#54b33e;">    caps = {
</span><span style="color:#54b33e;">    cons = cons_mux:svr(),   -- publish cons factory
</span><span style="color:#54b33e;">    fe   = L4.Env.log,       -- cons frontend (serial/stdio)
</span><span style="color:#54b33e;">    },
</span><span style="color:#ffffff;">}, "rom/cons -m l4re -f fe -a -c starforth")
</span><span style="color:#ffffff;">
</span><span style="color:#ffffff;">-- If your cons expects 'log' instead of 'fe', use this instead </span>:
<span style="color:#ffffff;">-- l </span>: <span style="color:#54b33e;">start({
</span><span style="color:#ffffff;">--   caps </span>= <span
      style="color:#54b33e;">{ cons = cons_mux:svr(), log = L4.Env.log },
</span><span style="color:#ffffff;">-- }, "rom/cons -m l4re -f log -a -c starforth")
</span><span style="color:#ffffff;">
</span><span style="color:#ffffff;">-- 3) tell loader to obtain log objects from cons (not the write-only logger)
</span><span style="color:#ffffff;">l.log_fab </span>= <span
      style="color:#54b33e;">cons_mux
</span><span style="color:#54b33e;">
</span><span style="color:#ffffff;">-- 4) start StarForth; loader asks cons to CREATE a NEW Vcon named 'starforth'
</span><span style="color:#ffffff;">l </span>: <span
      style="color:#54b33e;">start({
</span><span style="color:#54b33e;">    log = { "starforth", "yellow", "key=1", "show" },
</span><span style="color:#ffffff;">}, "rom/starforth")

</span></pre>
    </div>
    <p><br>
      <br>
    </p>
    <div class="moz-cite-prefix">On 9/3/25 15:03, Robert A. James wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:[email protected]">
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">
      <p>Hello l4-hackers,<br>
        <br>
        My name is Robert (Bob) A. James I'm VERY new to the L4Re world.
        This is also my first foray into systems programming having come
        from the Medical Device and Enterprise areas during my career. I
        am now retired and developing a full Operating System based on
        L4Re/Fiasco.OC.</p>
      <p data-start="202" data-end="356">I’m looking for guidance on the
        <em data-start="234" data-end="245">canonical</em> way to wire
        an interactive text console (stdin/stdout) for a user program
        under L4Re/Fiasco.OC on amd64-plain.</p>
      <p data-start="358" data-end="365">Context</p>
      <ul data-start="366" data-end="740">
        <li data-start="366" data-end="509">
          <p data-start="368" data-end="509">I have a small, headless
            FORTH VM (“StarForth”) running under L4Re/Fiasco.OC; its
            self-tests pass. What’s missing is an <strong
              data-start="488" data-end="508">interactive REPL</strong>.</p>
        </li>
        <li data-start="510" data-end="740">
          <p data-start="512" data-end="740">Target outcomes:<br>
            a) Run via <code data-start="542" data-end="580">make qemu
              E=starforth O=build-x86_64</code><br data-start="580"
              data-end="583">
            b) Build GRUB2 ISO via <code data-start="608"
              data-end="650">make grub2iso E=starforth O=build-x86_64</code><br
              data-start="650" data-end="653">
            c) ISO runs in QEMU and VirtualBox<br data-start="689"
              data-end="692">
            d) Same ISO boots on commodity x86_64 hardware</p>
        </li>
      </ul>
      <p data-start="742" data-end="779">What I’ve tried (and where I’m
        stuck)</p>
      <ol data-start="780" data-end="1783">
        <li data-start="780" data-end="1529">
          <p data-start="783" data-end="813"><strong data-start="783"
              data-end="798">Vcon + cons</strong> (almost there)</p>
          <ul data-start="817" data-end="1529">
            <li data-start="817" data-end="939">
              <p data-start="819" data-end="939">My mental model: Vcon
                as a frontend; <code data-start="856" data-end="862">cons</code>
                providing the console service; StarForth as the
                “backend” client/subscriber.</p>
            </li>
            <li data-start="943" data-end="1172">
              <p data-start="945" data-end="1172">Behavior I see:<br>
                • The “terminal” prints what the <strong
                  data-start="999" data-end="1009">logger</strong>
                prints rather than the process’s normal <strong
                  data-start="1050" data-end="1060">stdout</strong>.<br
                  data-start="1061" data-end="1064">
                • Output sometimes <strong data-start="1088"
                  data-end="1115">flushes only on newline</strong>;
                interactive prompts without <code data-start="1145"
                  data-end="1149">\n</code> don’t appear reliably.</p>
            </li>
            <li data-start="1176" data-end="1240">
              <p data-start="1178" data-end="1240">Aside from those two
                issues, this was close to a working REPL.</p>
            </li>
            <li data-start="1244" data-end="1529">
              <p data-start="1246" data-end="1529"><strong
                  data-start="1246" data-end="1260">Questions:</strong>
                Is <code data-start="1264" data-end="1270">cons</code>
                effectively write-only (log)? If so, what’s the
                supported input-capable console frontend to bind both
                stdin and stdout for a user process? Is there a minimal
                example showing correct capability wiring so user
                stdout/stderr don’t get mixed with the system log?</p>
            </li>
          </ul>
        </li>
        <li data-start="1531" data-end="1783">
          <p data-start="1534" data-end="1560"><strong data-start="1534"
              data-end="1560">GOOS/Framebuffer route</strong></p>
          <ul data-start="1564" data-end="1783">
            <li data-start="1564" data-end="1783">
              <p data-start="1566" data-end="1783">I attempted a tiny
                terminal server that maps the GOOS framebuffer and
                renders an 8×16 CP437 font. I did not get this path
                working end-to-end, so I’m fine dropping it if there’s a
                simpler, recommended console approach.</p>
            </li>
          </ul>
        </li>
      </ol>
      <p data-start="1785" data-end="1800">What would help</p>
      <ul data-start="1801" data-end="2184">
        <li data-start="1801" data-end="2036">
          <p data-start="1803" data-end="1924">The <strong
              data-start="1807" data-end="1838">recommended minimal
              pattern</strong> (modules/services + boot script) to give
            a user task a real interactive stdin/stdout:</p>
          <ul data-start="1927" data-end="2036">
            <li data-start="1927" data-end="1975">
              <p data-start="1929" data-end="1975">works with <code
                  data-start="1940" data-end="1953">make qemu …</code>
                and <code data-start="1958" data-end="1975">make
                  grub2iso …</code></p>
            </li>
            <li data-start="1978" data-end="2036">
              <p data-start="1980" data-end="2036">also works on typical
                PCs without a full graphics stack.</p>
            </li>
          </ul>
        </li>
        <li data-start="2037" data-end="2184">
          <p data-start="2039" data-end="2184">A <strong
              data-start="2041" data-end="2060">small reference</strong>
            that: (1) prints text, and (2) reads keystrokes from the
            user, with a snippet of <code data-start="2142"
              data-end="2156">modules.list</code> and the Lua loader
            snippet.</p>
        </li>
      </ul>
      <p data-start="2186" data-end="2207">Environment / details</p>
      <ul data-start="2208" data-end="2380">
        <li data-start="2208" data-end="2271">
          <p data-start="2210" data-end="2271">L4Re/Fiasco.OC on
            amd64-plain, built with the L4Re toolchain.</p>
        </li>
        <li data-start="2272" data-end="2380">
          <p data-start="2274" data-end="2380">Intended entry points: <code
              data-start="2297" data-end="2335">make qemu E=starforth
              O=build-x86_64</code>, <code data-start="2337"
              data-end="2379">make grub2iso E=starforth O=build-x86_64</code>.</p>
        </li>
      </ul>
      <p data-start="2382" data-end="2429">One of my simple boot
        variants (for reference):</p>
      <p data-start="2431" data-end="2458"><code data-start="2431"
          data-end="2445">modules.list</code> (simplified)</p>
      <pre class="overflow-visible!" data-start="2459" data-end="2581"><div
class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"><div
      style="background-color:#131314;color:#ebebeb"><pre
      style="font-family:'JetBrains Mono',monospace;font-size:9.8pt;">entry starforth
kernel fiasco -serial_esc
roottask moe rom/quark.cfg
module l4re
module ned
module cons
module quark.cfg
module starforth
</pre></div><code data-start="2583" data-end="2594">quark.cfg</code> --&gt; I think this is about what I had.</div></pre>
      <pre class="overflow-visible!" data-start="2615" data-end="2898"><div
class="contain-inline-size rounded-2xl relative bg-token-sidebar-surface-primary"><div
      style="background-color:#131314;color:#ebebeb"><pre
      style="font-family:'JetBrains Mono',monospace;font-size:9.8pt;"><span
      style="color:#ffffff;">-- rom/quark.cfg
</span><span style="color:#ffffff;">local L4 </span>= <span
      style="color:#54b33e;">require("L4")
</span><span style="color:#ffffff;">local ld </span>= <span
      style="color:#54b33e;">L4.default_loader
</span><span style="color:#54b33e;">
</span><span style="color:#ffffff;">-- Start cons; feed it to the real serial logger (fe </span>= <span
      style="color:#54b33e;">L4.Env.log)
</span><span style="color:#ffffff;">local cons_ctl </span>= <span
      style="color:#54b33e;">ld:new_channel()
</span><span style="color:#ffffff;">ld</span>:<span
      style="color:#54b33e;">start({
</span><span style="color:#54b33e;">   caps = {
</span><span style="color:#54b33e;">   cons = cons_ctl:svr(),  -- server gate for cons' factory
</span><span style="color:#54b33e;">   fe   = L4.Env.log,      -- cons frontend goes to serial/log
</span><span style="color:#54b33e;">   },
</span><span style="color:#ffffff;">}, "rom/cons -m l4re -f fe -a -t -c StarForth")  -- ← added -c StarForth
</span><span style="color:#ffffff;">
</span><span style="color:#ffffff;">-- Ask cons to create a Vcon client for StarForth and pass it in as 'tty'
</span><span style="color:#ffffff;">-- (Capabilities are first-class in Ned; calling 'create' on caps is supported.)
</span><span style="color:#ffffff;">local tty </span>= <span
      style="color:#54b33e;">cons_ctl:create(L4.Proto.Log, "StarForth", "show", "key=1", "bufsz=65536")
</span><span style="color:#54b33e;">
</span><span style="color:#ffffff;">-- Start StarForth with that Vcon as its TTY
</span><span style="color:#ffffff;">ld</span>:<span
      style="color:#54b33e;">start({
</span><span style="color:#54b33e;">   caps = {
</span><span style="color:#54b33e;">   tty = tty,  -- the Vcon client for StarForth
</span><span style="color:#54b33e;">   },
</span><span style="color:#ffffff;">}, "rom/starforth")
</span></pre></div>I can share a minimal reproducible case (sources, build logs, QEMU output) off-list if that helps.</div></pre>
      <p data-start="3000" data-end="3095">Thanks in advance for any
        pointers to the “right way,” or to a maintained example I can
        follow.</p>
      <p data-start="3097" data-end="3199" data-is-last-node=""
        data-is-only-node="">Best regards,<br data-start="3110"
          data-end="3113">
        R. A. “Bob” James (<a
          class="moz-txt-link-abbreviated moz-txt-link-freetext"
          href="mailto:[email protected]" moz-do-not-send="true">[email protected]</a>)</p>
      <p data-start="3097" data-end="3199" data-is-last-node=""
        data-is-only-node="">Kubuntu 25.04 • amd64-plain •
        QEMU/VirtualBox • GRUB2 boot targets</p>
      <br>
      <fieldset class="moz-mime-attachment-header"></fieldset>
      <pre wrap="" class="moz-quote-pre">_______________________________________________
l4-hackers mailing list -- <a class="moz-txt-link-abbreviated" href="mailto:[email protected]">[email protected]</a>
To unsubscribe send an email to <a class="moz-txt-link-abbreviated" href="mailto:[email protected]">[email protected]</a>
</pre>
    </blockquote>
  </body>
  <lt-container></lt-container>
</html>

--------------3Uuv5snkeSjfo1H4UJhWG0a4--

--===============0324897902204933820==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
l4-hackers mailing list -- [email protected]
To unsubscribe send an email to [email protected]

--===============0324897902204933820==--