APC8750にNetBSD/evbarmを移植するための記録 5/8
2014/01/04(土) 13:57 NetBSD はてブ情報 はてブに登録 はてブ数

MMUをonにするところで挫折しては以前から何の進歩もないのでしぶとくデバッグを続けていたところ、デバッグルーチンがレジスタを上書きしていたのにやっと気づいた。

ついにapc_machdep.cのinitarmに飛び込んだ!
たった一文字アットマークが表示されるだけなのだけど、とても嬉しい。

やっぱり無精をせずにレジスタまで意識しながら読まないとダメなのだなぁと思い知らされました。

apc_start.Sでは0xD8200000つまり物理アドレス(PA)に値を書き込めばシリアルから出力されますが、apc_machdep.cでは仮想アドレス(VA)でアクセスする必要があるのですね。

initarmの冒頭で次のように書くとシリアルにアットマークが出力されます。
      *(volatile int *)0xfe200000  = 0x40;

APC8750にNetBSD/evbarmを移植するための記録 3/25 ~ 3/31
2014/01/04(土) 13:42 NetBSD はてブ情報 はてブに登録 はてブ数

3/25

NetBSDカーネルを読み込ませるにはu-bootを使わねば、ということでu-bootで何ができるか調べる。
helpと入力するとコマンド一覧が表示される。
WMT # help
?       - alias for 'help'
autoscr - run script from memory
base    - print or set address offset
bdinfo  - print Board Info structure
boot    - boot default, i.e., run 'bootcmd'
bootd   - boot default, i.e., run 'bootcmd'
bootm   - boot application image from memory
bootp   - boot image via network using BootP/TFTP protocol
cmp     - memory compare
coninfo - print console devices and information
cp      - memory copy
crc32   - checksum calculation
dhcp    - invoke DHCP client to obtain IP/boot params
diskboot- boot from IDE device
show    -
dmacp     - dma memory copy
echo    - echo args to console
erase   - erase FLASH memory
exit    - exit script
fatinfo - print information about filesystem
fatload - load binary file from a dos filesystem
fatls   - list files in a directory (default /)
fatstore - store binary file to a dos filesystem
flinfo  - print FLASH memory information
go      - start application at address 'addr'
help    - print online help
icrc32  - checksum calculation
ide     - IDE sub-system
iloop   - infinite loop on address range
imd     - i2c memory display
iminfo  - print header information for application image
imls    - list all images found in flash
imm     - i2c memory modify (auto-incrementing)
ims  - set i2c device context from memory
imw     - memory write (fill)
inm     - memory modify (constant address)
iprobe  - probe to discover valid I2C chip addresses
itest   - return true/false on integer compare
loadb   - load binary file over serial line (kermit mode)
loads   - load S-Record file over serial line
loop    - infinite loop on address range
memory bit operation :
Format : mbit <parameter>
md      - memory display
mii     - MII utility commands
mm      - memory modify (auto-incrementing)
mmcinit - init mmc card
  mmcinit 0 -- init mmc device 0
  mmcinit 1 -- init mmc device 1
  mmcinit 2 -- init mmc device 2
mmcread - read data from SD/MMC card
  <dev_id> <addr> <block_num> <bytes>
   -read data from SD/MMC card block address 'block_num' on 'dev_id'
    to memory address 'addr' size is 'bytes'
mmcwrite - write data to SD/MMC card
  <dev_id> <addr> <block_num> <bytes>
   -write data to SD/MMC card block address 'block_num' on 'dev_id'
    from memory address 'addr' size is 'bytes'
mtest   - simple RAM test
mw      - memory write (fill)
nandrw  - NAND sub-system
nboot   - boot from NAND device
nfs     - boot image via network using NFS protocol
nm      - memory modify (constant address)
ping    - send ICMP ECHO_REQUEST to network host
printenv- print environment variables
protect - enable or disable FLASH write protection
rarpboot- boot image via network using RARP/TFTP protocol
reset   - Perform RESET of the CPU
run     - run commands in an environment variable
saveenv - save environment variables to persistent storage
sdwaitins - wait sd card inserted or removed
sdwaitins 0 -- waiting removed
sdwaitins 1 -- waiting inserted
setenv  - set environment variables
sleep   - delay execution for some time
test    - minimal test like /bin/sh
textout - show text to the screen
textout x y "str" color
color is 24bit Hex, R[23:16], G[15:8], B[7:0]
for example: textout 0 0 "hello world" FFFFFF
tftpboot- boot image via network using TFTP protocol
usb     - USB sub-system
usbboot - boot from USB device
version - print monitor version
WMT #
コマンドをGoogle検索をしているなかで、清水さんがFONにNetBSDを移植している日記を発見。

u-bootのコマンドラインからmm.lでメモリに直接値を書き込む技を知る。これを応用すれば、シリアル出力をつかさどるアドレスにmm.lで値を書き込むことによって文字が表示される。

APCはどのアドレスに書けばよいのかLinuxのソースをあたったところ、UART0のアドレスが0xD8200000であることを知る。
(https://github.com/apc-io/apc-8750/blob/master/kernel/arch/arm/mach-wmt/include/mach/wmt_mmap.h#L149)
WMT # mm.l d8200000
d8200000: 0000003a ? 40
@d8200004: 0000000d ? .
この場合、40という値を書き込むことで、シリアルからASCIIコードの@が出力されている。これでシリアルへの出力はできそうだ。

次はカーネルをどう読ませるかだが、u-bootにtftpbootがある。help tftpbootで使い方が出る。
WMT # help tftpboot
tftpboot [loadAddress] [bootfilename]
それはよいのだが、どこからファイルを持ってくるのかわからない。が、検索すれば何でも出てくる時代、tftpサーバの指定方法がset serverip [IPアドレス]で可能であることを知る。

とりあえず、TFTPを使ってカーネルをロードし、goコマンドでNetBSDカーネルが実行できそうだ。ということで、RPiをコピーして、色々削りまくって、カーネルがリンクできるところまでやっつける。

最初に実行されるのは、apc_start.Sなので、そこでmm.lと同様のことをすれば文字は出る。

と、evbarm/netwalker/netwalker_start.Sを見るとアセンブラで書かれた文字出力ルーチン(print_r3)があるではないか。シリアルのアドレスをちょっと調整すると動くようになった。アセンブリ言語音痴の自分にとってはよいお手本になった。armadillo_start.Sにもprint_r3がある。こっちが先かな?

print_r3を見るとステータスレジスタを確認して、出力してよい、というビットが立つまで待つ処理がある。mm.lコマンドで一文字出す分には気にする必要はないが、シリアルにたくさんの文字を文字を出力する際には必要なのだろう。

同じことをするためにはシリアルのステータスレジスタの情報が必要で、これらは、kernel/arch/arm/mach-wmt/include/mach/wmt_uart.h
に書かれている。ステータスレジスタは#define UART0_URUSR_ADDRで定義されており、
TXがビジーかどうか確認するのは#define URUSR_TXDBSYで定義されている。
putc_r0:
        stmfd   sp!, {r0, r1, r2, lr}
        ldr     r1, Luart0adr

1:      /* wait */
        ldr     r2, [r1, #0x1c]         /* load status register */
        tst     r2, #0x2 /* TX busy? (r2 & 0x0002) if busy then Z=0*/
        bne     1b /* if(Z==0) goto 1b */

        /* output */
        strb    r0, [r1, #0x00]
        ldmfd   sp!, {r0, r1, r2, pc}

3/31

apc_start.Sのprint_r3を使ってどこまで進んだかを表示させつつデバッグを進める。

例によって、MMUをonにするところから先に行けない。MMUをonにすると、デバッグ用のprint_r3が使えないため、何がどうなっているのかわからない。

いつもここで詰まってしまう。

APC8750にNetBSD/evbarmを移植するための記録 2/28 ~ 3/15
2014/01/03(金) 26:40 NetBSD はてブ情報 はてブに登録 はてブ数

NetBSDは多くのハードウェアで動作するので、色々なハードウェアを買ってきては動かして楽しんでいましたが、いつかは先人のように新しい機械に移植したいと思いつつ、いつも途中で挫折してきました。

ここ最近のARMアーキテクチャの隆盛をみていると、ほとんど同じだけどちょっと違う、みたいなハードウェアがたくさんあって、ちょっとした修正でNetBSDを移植した感動を味わえるんじゃないかと思い、入手したのがVIAのAPC8750です。

10/24の日記にも書いたとおり、シェルからコマンドを実行できる程度に動いたので、その顛末を記録しておこうと思いました。

実は、移植を始めた当初は記録をまともにつけておらず、ちゃんと記録を付け始めたのは8/24のようです。それまでの作業はTwitterと記憶によって補完したものです。

ということで、8/24まではアッサリ味でいきます。

2/28

移植用のARM板を探す。とりあえず、Raspberry Pi(以下、RPi)が流行っているから、きっと似たような奴がいっぱいいるに違いない。そいつらなら、ちょこっと修正してNetBSD動くんじゃないか? あと手ごろな値段がいいなぁ。もちろんシリアルは必要だな。できれば、ハンダ付けなしでシリアルが使えるといいな。などとWebを見ているとAPC8750にたどり着いた。こいつもRPiと同じARM11らしい。そういえば、ちょっと前に話題になってたなぁ。話題になってたから、きっといろいろ情報あるんだろう。ということで、あまり下調べもせずAPC8750を注文。

3/1

ハードウェアが届くまでの予習としてrpi_start.Sを読み始める。以前、スタートアップルーチンを読んだがどうしてもMMUをONにした後に進めなかった。アセンブリ言語で書かれているが、短いプログラムなので頑張れば全体を把握できそうだし、ARMアーキテクチャの勉強にもなるかと思い、命令一つ一つを読んでいく。

3/9

APCが届く。とりあえず、箱から出して撮影する。

CPUはWonderMediaのWM8759か。そうはいってもARMだし、などと楽観的に気持ちを切り替えてCPUについて調べ始める。

なんと、CPUのデータシートが公開されていないではないか。
デートシータがなければLinuxソースしかないか。githubにあった(https://github.com/apc-io/apc-8750)。


生まれて初めてgitをインストール。pkgsrcは便利だ。Linuxのカーネルは土地勘がないためgrepをかけまくる。

LinuxにおけるCPU依存部分(ボード依存部分も含む?)はkernel/arch/arm/mach-wmtの下を重点的に見ればよいようだ。
たとえば、kernel/arch/arm/mach-wmt/include/mach/wmt_mmap.hはメモリマップであるとか。

3/15


本丸のevbarm/rpiの下をちょろちょろとのぞくようになる。nxr.netbsd.orgのOpenGrokのロゴがなぜか「理解開く」という日本語になる。

Challenging Lua in the NetBSD kernel
2014/01/02(木) 18:16 NetBSD はてブ情報 はてブに登録 はてブ数

Preparation

dec27# uname -a
NetBSD dec27 6.99.28 NetBSD 6.99.28 (GENERIC) #0: Fri Dec 27 23:23:48 UTC 2013  builds@b8.netbsd.org:/home/builds/ab/HEAD/amd64/201312272220Z-obj/home/builds/ab/HEAD/src/sys/arch/amd64/compile/GENERIC amd64
Run as root user.
$ su -
Terminal type is xterm.
dec27#
Run luactl(8).
dec27# luactl
luactl: /dev/lua: Device not configured
dec27# tail -1 /var/log/messages
Jan  2 07:18:18 dec27 /netbsd: WARNING: module error: incompatible module class for `lua' (3 != 1)
Load the module of Lua.
dec27# modload lua
dec27# tail -1 /var/log/messages
Jan  2 07:19:42 dec27 /netbsd: lua0: Lua 5.1.5  Copyright (C) 1994-2012 Lua.org, PUC-Rio
Run luactl.
dec27# luactl
0 active states:
OK!

Check kernel status by sysctl.
Set the verbose option for debug.
dec27# sysctl -a|grep kern.lua
kern.lua.require = 1
kern.lua.autoload = 1
kern.lua.bytecode = 0
kern.lua.verbose = 0
kern.lua.maxcount = 0
dec27# sysctl -w kern.lua.verbose=1
kern.lua.verbose: 0 -> 1
Create the new state of Lua.
dec27# luactl create s1
s1 created
dec27# tail -1 /var/log/messages
Jan  2 07:25:15 dec27 /netbsd: lua0: state s1 created
dec27# luactl
1 active state:
Name             Creator  Description
s1               user

Hello world!

Create a file(hello1.lua).
dec27# cat hello1.lua
-- hello world!
print("hello world!\n")
Run hello1.lua by luactl.
dec27# luactl load s1 ./hello1.lua
luactl: LUALOAD: Invalid argument
dec27# tail -2 /var/log/messages
Jan  2 07:28:38 dec27 /netbsd: lua0: loading ./hello1.lua into state s1
Jan  2 07:28:38 dec27 /netbsd: lua0: execution error: [string "hello1.lua"]:2: attempt to call global 'print' (a nil value)
Load the system module(luasystm.kmod) for print().
dec27# modload luasystm
dec27# tail -1 /var/log/messages
Jan  2 07:28:02 dec27 /netbsd: lua0: registered lua module systm
dec27# modstat|grep lua
lua              misc       filesys    1     ffffffff81168000 123347   -
luasystm         misc       filesys    0     ffffffff81187000 1784     lua
Modify to systm.print() from print().
dec27# cat hello1.lua
-- hello world!
systm.print("hello world!\n")
Run hello1.lua.
dec27# luactl load s1 ./hello1.lua
luactl: LUALOAD: Invalid argument
dec27# tail -2 /var/log/messages
Jan  2 07:32:53 dec27 /netbsd: lua0: loading ./hello1.lua into state s1
Jan  2 07:32:53 dec27 /netbsd: lua0: execution error: [string "hello1.lua"]:2: attempt to index global 'systm' (a nil value)
Enable the system module by luactl.
dec27# luactl require s1 systm
systm required by s1
dec27# tail -1 /var/log/messages
Jan  2 07:33:55 dec27 /netbsd: lua0: requiring module systm to state s1
Try again.
dec27# luactl load s1 ./hello1.lua
./hello1.lua loaded into s1
dec27# tail -2 /var/log/messages
Jan  2 07:35:16 dec27 /netbsd: lua0: loading ./hello1.lua into state s1
Jan  2 07:35:16 dec27 /netbsd: hello world!
OK!

Call other functions of system module.

dec27# cat hello2.lua
-- print systm.xxx (src/sys/module/luasystm/luasystm.c)
function uname()
  tbl = {"copyright", "cpu_model", "machine", "machine_arch", "osrelease", "ostype", "kernel_ident", "version"}
  for i = 1, #tbl do
    systm.print(systm[tbl[i]] .. "\n")
  end
end

-- hello world!
systm.print("hello world!\n")

-- print systm.xxx
uname()
Run hello2.lua.
dec27# luactl load s1 ./hello2.lua
./hello2.lua loaded into s1
dec27# tail -18  /var/log/messages
Jan  2 07:36:58 dec27 /netbsd: lua0: loading ./hello2.lua into state s1
Jan  2 07:36:58 dec27 /netbsd: hello world!
Jan  2 07:36:58 dec27 /netbsd: Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
Jan  2 07:36:58 dec27 /netbsd:    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013
Jan  2 07:36:58 dec27 /netbsd:    The NetBSD Foundation, Inc.  All rights reserved.
Jan  2 07:36:58 dec27 /netbsd: Copyright (c) 1982, 1986, 1989, 1991, 1993
Jan  2 07:36:58 dec27 /netbsd:    The Regents of the University of California.  All rights reserved.
Jan  2 07:36:58 dec27 /netbsd:
Jan  2 07:36:58 dec27 /netbsd:
Jan  2 07:36:58 dec27 /netbsd: Intel 686-class
Jan  2 07:36:58 dec27 /netbsd: amd64
Jan  2 07:36:58 dec27 /netbsd: x86_64
Jan  2 07:36:58 dec27 /netbsd: 6.99.28
Jan  2 07:36:58 dec27 /netbsd: NetBSD
Jan  2 07:36:58 dec27 /netbsd: GENERIC
Jan  2 07:36:58 dec27 /netbsd: NetBSD 6.99.28 (GENERIC) #0: Fri Dec 27 23:23:48 UTC 2013
Jan  2 07:36:58 dec27 /netbsd:  builds@b8.netbsd.org:/home/builds/ab/HEAD/amd64/201312272220Z-obj/home/builds/ab/HEAD/src/sys/arch/amd64/compile/GENERIC
Jan  2 07:36:58 dec27 /netbsd:
OK!

Call the function of another file.

Create & load new file(add.lua).
dec27# cat add.lua
function add(x, y)
 return x + y
end
dec27# luactl load s1 ./add.lua
./add.lua loaded into s1
dec27# tail -1 /var/log/messages
Jan  2 07:39:57 dec27 /netbsd: lua0: loading ./add.lua into state s1
Create & run hello3.lua.
dec27# cat hello3.lua
-- hello world!
systm.print("hello world!\n")

-- call function on add.lua
systm.print("1 + 2 = " .. add(1,2) .. "\n")
dec27# luactl load s1 ./hello3.lua
./hello3.lua loaded into s1
dec27# tail -3 /var/log/messages
Jan  2 07:41:32 dec27 /netbsd: lua0: loading ./hello3.lua into state s1
Jan  2 07:41:32 dec27 /netbsd: hello world!
Jan  2 07:41:32 dec27 /netbsd: 1 + 2 = 3
OK!

Call the lua function from C function in kernel module.

hello4.lua
  -> lcl(x, y) @ lualabo.kmod
    -> add(x, y) @ add.lua
Make directories for kernel module (lualabo).
dec27# mkdir /stand/amd64/6.99.28/modules/lualabo
dec27# mkdir /usr/src/sys/modules/lualabo
dec27# cd /usr/src/sys/modules/lualabo
Create sources of kernel module based on /usr/src/sys/modules/luasystm.
dec27# cat Makefile
#       $NetBSD$

.include "../Makefile.inc"

KMOD=           lualabo
SRCS=           lualabo.c

CPPFLAGS+=      -I${S}/../external/mit/lua/dist/src \
                -I${S}/modules/lua

.include <bsd.kmodule.mk>
dec27#
dec27#
dec27# cat lualabo.c
/*      $NetBSD$ */

/*
 * Copyright (c) 2011, 2013 Marc Balmer <mbalmer@NetBSD.org>.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the Author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

/* Lua labo kernel services module */

#include <sys/param.h>
#include <sys/lua.h>
#include <sys/callout.h>
#ifdef _MODULE
#include <sys/module.h>
#endif
#include <sys/systm.h>

#include <lua.h>
#include <lauxlib.h>

#ifdef _MODULE
MODULE(MODULE_CLASS_MISC, lualabo, "lua");

static int
lcl(lua_State *L)
{
        int x,y;

        x = lua_tointeger(L, -2);
        y = lua_tointeger(L, -1);

        lua_getglobal(L, "add");
        lua_pushnumber(L, x);
        lua_pushnumber(L, y);
        lua_pcall(L, 2, 1, 0); /* 2 args, 1 ret */

        printf("lcl()@lualabo: add = %d\n", (int) lua_tointeger(L, -1));

        return 0;
}
/* callouts */

/* mutexes */

static const luaL_Reg labo_lib[ ] = {
        { "lcl",                        lcl },

        /* callouts */

        /* mutexes */

        {NULL, NULL}
};


static int
luaopen_labo(void *ls)
{
        lua_State *L = (lua_State *)ls;

        luaL_register(L, "labo", labo_lib);

        return 1;
}

static int
lualabo_modcmd(modcmd_t cmd, void *opaque)
{
        int error;

        switch (cmd) {
        case MODULE_CMD_INIT:
                error = lua_mod_register("labo", luaopen_labo);
                break;
        case MODULE_CMD_FINI:
                error = lua_mod_unregister("labo");
                break;
        default:
                error = ENOTTY;
        }
        return error;
}
#endif
Build & install lualabo.kmod.
dec27# /usr/obj/tooldir.NetBSD-6.99.28-amd64/bin/nbmake-amd64
dec27# cp lualabo.kmod /stand/amd64/6.99.28/modules/lualabo/
Load lualabo.
dec27# modload lualabo
dec27# tail -1 /var/log/messages
Jan  2 07:49:16 dec27 /netbsd: lua0: registered lua module labo
dec27#
dec27# luactl require s1 labo
labo required by s1
dec27# tail -1 /var/log/messages
Jan  2 07:49:44 dec27 /netbsd: lua0: requiring module labo to state s1
Create hello4.lua.
dec27# cat hello4.lua
-- hello world!
systm.print("hello world!\n")

-- call function on add.lua via lualabo.kmod
labo.lcl(2, 4)
Run hello4.lua.
dec27# luactl load s1 ./hello4.lua
./hello4.lua loaded into s1
dec27# tail -3 /var/log/messages
Jan  2 07:51:39 dec27 /netbsd: lua0: loading ./hello4.lua into state s1
Jan  2 07:51:39 dec27 /netbsd: hello world!
Jan  2 07:51:39 dec27 /netbsd: lcl()@lualabo: add = 6

NetBSDカーネル内部で動作するLuaを試す
2013/12/14(土) 5:06 NetBSD はてブ情報 はてブに登録 はてブ数

NetBSDカーネル内部でLuaが動作するというのはGSoC 2010から始まり、成果が出たという報告の後、少しの間が空いて、2013年10月に本体にマージされたというニュースが話題になりました。

これを機に、新しいプログラミング言語を覚えようということで動作をさせるべく試してみました。

動作確認した環境はNetBSD/amd64 20131208です。

まず、luaデバイスを作ります。
# cd /dev
# ./MAKEDEV lua
モジュールを二つロードします。luacoreというのはprintなどを使うために必要です。
# modload lua
# modload luacore
luaモジュールをロードすると/var/log/messagesに次のようなログが出ます。
Dec 14 19:13:52 dec /netbsd: lua0: Lua 5.1.5  Copyright (C) 1994-2012 Lua.org, PUC-Rio
sysctlを使ってlua関係の操作が詳細に表示されるようにしておくと便利です。最初はうまく動かず苦労したのですが、この設定をしておくとエラーが詳細に表示されるので非常に助かりました。
# sysctl -w kern.lua.verbose=1
kern.lua.verbose: 0 -> 1
Luaのステータスを作ります。コンテキストみたいなものかなぁ。
# luactl create s1
s1 created
/var/log/messagesに次のようなログが出ます。
Dec 14 19:14:28 dec /netbsd: lua0: state s1 created
coreモジュールを使えるようにします。
# luactl require s1 core
core required by s1
/var/log/messagesに次のようなログが出ます。
Dec 14 19:14:53 dec /netbsd: lua0: requiring module core to state s1
Luaスクリプトを作ります。やはりhello world!です。
# cat test.lua
core.print("hello world!\n")
スクリプトをロードして実行します。
# luactl load s1 ./test.lua
./test.lua loaded int s1
実行結果は/var/log/messagesを見るとわかります。
Dec 14 19:15:40 dec /netbsd: lua0: loading ./test.lua into state s1
Dec 14 19:15:40 dec /netbsd: hello world!
luacoreのソースを見ると、printだけでなく様々な関数が用意されています。

やはり、panicは試してみたいところです。

先のスクリプトのprintをpanicに置き換えますと、ちゃんとpanicしました。
hello world!とのんびりと世界に挨拶をしつつpanicによって世界が崩壊するさまは、なかなか味わい深いものでした。