From eb3900355dc35f6735309e120deefd65488f0de4 Mon Sep 17 00:00:00 2001 From: itsmanjeet Date: Sun, 29 Dec 2024 23:07:02 +0530 Subject: [PATCH] tools/dbg: added adb like serial port debugger tool for rlxos --- core/cmd/dbgd/dbgd.service | 4 - core/cmd/dbgd/main.go | 89 ----------------- core/cmd/shell/shell@.service | 2 +- ...shell@tty9.service => shell@ttyS0.service} | 0 core/pkg/service/service.go | 9 +- devices/generic/x86_64/make-iso.sh | 4 +- devices/generic/x86_64/toolchain.conf | 2 + go.work | 1 + tools/dbg/exec.go | 21 ++++ tools/dbg/main.go | 96 +++++++++---------- tools/dbg/pull.go | 55 +++++++++++ tools/dbg/push.go | 47 +++++++++ tools/dbg/shell.go | 13 +++ 13 files changed, 196 insertions(+), 147 deletions(-) delete mode 100644 core/cmd/dbgd/dbgd.service delete mode 100644 core/cmd/dbgd/main.go rename core/cmd/shell/{shell@tty9.service => shell@ttyS0.service} (100%) create mode 100644 tools/dbg/exec.go create mode 100644 tools/dbg/pull.go create mode 100644 tools/dbg/push.go create mode 100644 tools/dbg/shell.go diff --git a/core/cmd/dbgd/dbgd.service b/core/cmd/dbgd/dbgd.service deleted file mode 100644 index 8483452a..00000000 --- a/core/cmd/dbgd/dbgd.service +++ /dev/null @@ -1,4 +0,0 @@ -kind: service -exec-start: /core/dbgd -debug -user: system -restart: true diff --git a/core/cmd/dbgd/main.go b/core/cmd/dbgd/main.go deleted file mode 100644 index 3a4223de..00000000 --- a/core/cmd/dbgd/main.go +++ /dev/null @@ -1,89 +0,0 @@ -package main - -import ( - "bufio" - "flag" - "fmt" - "io" - "log" - "net" - "os" - "os/exec" - "strings" -) - -var ( - port string - debug bool -) - -func init() { - flag.StringVar(&port, "port", "5555", "port to connect to") - flag.BoolVar(&debug, "debug", false, "enable debug logging") -} - -func main() { - flag.Parse() - - if !debug { - log.SetOutput(io.Discard) - } - - listener, err := net.Listen("tcp", ":"+port) - if err != nil { - _, _ = fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } - defer listener.Close() - - log.Printf("Listening on port %s", port) - for { - conn, err := listener.Accept() - if err != nil { - _, _ = fmt.Fprintln(os.Stderr, err) - continue - } - handleConn(conn) - } -} - -func handleConn(conn net.Conn) { - defer conn.Close() - - reader := bufio.NewReader(conn) - input, err := reader.ReadString('\n') - if err != nil { - _, _ = fmt.Fprintln(os.Stderr, err) - return - } - args := strings.Split(strings.TrimSpace(input), " ") - if len(args) < 1 { - _, _ = fmt.Fprintf(conn, "Usage: dbg \n") - return - } - switch args[0] { - case "exec": - if len(args) == 1 { - _, _ = fmt.Fprintf(conn, "Usage: dbg exec \n") - } - output, err := exec.Command(args[1], args[2:]...).CombinedOutput() - if err != nil { - _, _ = fmt.Fprintf(os.Stderr, "%s: %s\n", string(output), err) - return - } - _, err = fmt.Fprint(conn, string(output)) - if err != nil { - log.Println("ERROR: failed to write output to exec:", err) - } - case "shell": - cmd := exec.Command("/core/shell") - cmd.Stdin = conn - cmd.Stdout = conn - cmd.Stderr = conn - if err := cmd.Run(); err != nil { - _, _ = fmt.Fprintln(os.Stderr, err) - } - default: - _, _ = fmt.Fprintf(conn, "Usage: dbg \n") - } -} diff --git a/core/cmd/shell/shell@.service b/core/cmd/shell/shell@.service index 1681a4d1..ed988f4c 100644 --- a/core/cmd/shell/shell@.service +++ b/core/cmd/shell/shell@.service @@ -1,3 +1,3 @@ -exec-start: /core/shell +exec-start: /bin/sh restart: true tty: /dev/%i diff --git a/core/cmd/shell/shell@tty9.service b/core/cmd/shell/shell@ttyS0.service similarity index 100% rename from core/cmd/shell/shell@tty9.service rename to core/cmd/shell/shell@ttyS0.service diff --git a/core/pkg/service/service.go b/core/pkg/service/service.go index b93da987..8cc7624e 100644 --- a/core/pkg/service/service.go +++ b/core/pkg/service/service.go @@ -127,7 +127,9 @@ func (s *Service) Start(journal *os.File) error { } uid, gid := 0, 0 - groups := []uint32{} + var groups []uint32 + + ttyOwner := false if s.User != "" { usr, err := user.Lookup(s.User) if err != nil { @@ -181,6 +183,10 @@ func (s *Service) Start(journal *os.File) error { cmd := exec.Command(args[0], args[1:]...) if s.TTY != "" { + ttyOwner = true + if err := os.Chown(s.TTY, uid, gid); err != nil { + return err + } tty, err := os.OpenFile(s.TTY, os.O_RDWR, 0) if err != nil { return err @@ -199,6 +205,7 @@ func (s *Service) Start(journal *os.File) error { Gid: uint32(gid), Groups: groups, }, + Setsid: ttyOwner, } if err := cmd.Start(); err != nil { diff --git a/devices/generic/x86_64/make-iso.sh b/devices/generic/x86_64/make-iso.sh index 498d3657..1cf495da 100644 --- a/devices/generic/x86_64/make-iso.sh +++ b/devices/generic/x86_64/make-iso.sh @@ -41,7 +41,7 @@ set timeout=10 menuentry "RLXOS GNU/Linux" { insmod all_video - linux /boot/bzImage root=LABEL=RLXOS rootfs-type=iso9660 live quiet console=tty0 console=ttyS0,115200 + linux /boot/bzImage root=LABEL=RLXOS rootfs-type=iso9660 live quiet console=ttyS0 initrd /boot/initramfs.img } EOF @@ -50,7 +50,7 @@ install -vDm0644 /dev/stdin $BINARIES_DIR/iso/isolinux/isolinux.cfg << EOF DEFAULT RLXOS LABEL RLXOS KERNEL /boot/bzImage - APPEND initrd=/boot/initramfs.img root=LABEL=RLXOS rootfs-type=iso9660 live quiet console=tty0 console=ttyS0,115200 + APPEND initrd=/boot/initramfs.img root=LABEL=RLXOS rootfs-type=iso9660 live quiet console=ttyS0 EOF cp $BINARIES_DIR/bzImage \ diff --git a/devices/generic/x86_64/toolchain.conf b/devices/generic/x86_64/toolchain.conf index 339f5d74..f6de7506 100644 --- a/devices/generic/x86_64/toolchain.conf +++ b/devices/generic/x86_64/toolchain.conf @@ -50,6 +50,8 @@ BR2_PACKAGE_CA_CERTIFICATES=y BR2_PACKAGE_WLROOTS=y BR2_PACKAGE_WLROOTS_X11=y BR2_PACKAGE_WLROOTS_XWAYLAND=y +BR2_PACKAGE_SEATD_BUILTIN=y +BR2_PACKAGE_SEATD_DAEMON=y BR2_TARGET_ROOTFS_SQUASHFS=y # BR2_TARGET_ROOTFS_TAR is not set BR2_TARGET_GRUB2=y diff --git a/go.work b/go.work index faf4be0a..84cfee52 100644 --- a/go.work +++ b/go.work @@ -3,6 +3,7 @@ go 1.22 use ( ./devices/generic ./tools/ignite + ./tools/dbg ./core ./desktop ./kernel diff --git a/tools/dbg/exec.go b/tools/dbg/exec.go new file mode 100644 index 00000000..3036503e --- /dev/null +++ b/tools/dbg/exec.go @@ -0,0 +1,21 @@ +package main + +import ( + "bufio" + "fmt" + "strings" +) + +func exec(args []string) error { + _, err := conn.Write([]byte(strings.Join(args, " ") + "\n")) + if err != nil { + return err + } + reader := bufio.NewReader(conn) + response, err := reader.ReadString('\n') + if err != nil { + return err + } + fmt.Print(response) + return nil +} diff --git a/tools/dbg/main.go b/tools/dbg/main.go index b180ce97..f851e494 100644 --- a/tools/dbg/main.go +++ b/tools/dbg/main.go @@ -4,79 +4,75 @@ import ( "bufio" "flag" "fmt" - "io" - "log" "net" "os" "strings" ) var ( - addr string - debug bool + addr string + conn net.Conn + commands = map[string]func([]string) error{ + "exec": exec, + "push": push, + "pull": pull, + "shell": shell, + } + err error ) func init() { - flag.StringVar(&addr, "addr", "", "the address to connect to") - flag.BoolVar(&debug, "debug", false, "debug mode") + flag.StringVar(&addr, "addr", "localhost:5555", "Serial Port") +} + +func printHelp() { + flag.Usage() } func main() { flag.Parse() - if !debug { - log.SetOutput(io.Discard) + + if len(flag.Args()) == 0 { + printHelp() + os.Exit(1) } - conn, err := net.Dial("tcp", addr) + cmd, ok := commands[flag.Arg(0)] + if !ok { + printHelp() + os.Exit(1) + } + + conn, err = net.Dial("tcp", addr) if err != nil { _, _ = fmt.Fprintln(os.Stderr, err) os.Exit(1) } defer conn.Close() - args := flag.Args() - - if len(args) == 0 { - return + if err := cmd(flag.Args()[1:]); err != nil { + _, _ = fmt.Fprintln(os.Stderr, err) + os.Exit(1) } +} - switch args[0] { - case "shell": - go func() { - _, _ = io.Copy(os.Stdout, conn) - _, _ = io.Copy(os.Stderr, conn) - }() - log.Println("Starting shell") - if _, err := conn.Write([]byte(args[0] + "\n")); err != nil { - _, _ = fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } - - _, err := io.Copy(conn, os.Stdin) - if err != nil { - _, _ = fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } - default: - cmd := strings.Join(flag.Args(), " ") - log.Printf("Sending '%s' to %s\n", cmd, conn.RemoteAddr()) - if _, err := conn.Write([]byte(cmd + "\n")); err != nil { - _, _ = fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } - - reader := bufio.NewReader(conn) - for { - out, err := reader.ReadString('\n') - if err != nil { - if err != io.EOF { - _, _ = fmt.Fprintln(os.Stderr, err) - os.Exit(1) - } - break - } - fmt.Print(out) - } +func receive() (string, error) { + reader := bufio.NewReader(conn) + resp, err := reader.ReadString('\n') + if err != nil { + return "", err } + return strings.TrimSpace(resp), nil +} +func send(cmd string) (string, error) { + _, err := conn.Write([]byte(cmd + "\n")) + if err != nil { + return "", err + } + resp, err := receive() + if err != nil { + return "", err + } + return resp, nil } diff --git a/tools/dbg/pull.go b/tools/dbg/pull.go new file mode 100644 index 00000000..3fe6d13a --- /dev/null +++ b/tools/dbg/pull.go @@ -0,0 +1,55 @@ +package main + +import ( + "fmt" + "io" + "os" + "strconv" + "strings" +) + +func pull(args []string) error { + if len(args) != 2 { + return fmt.Errorf("usage: dbg pull ") + } + source := args[0] + destination := args[1] + + resp, err := send(fmt.Sprintf("download %s", source)) + if err != nil { + return err + } + + if !strings.HasPrefix(resp, "SIZE") { + return fmt.Errorf("bad response: %s", resp) + } + + sizeStr := strings.TrimSpace(strings.Split(resp, " ")[1]) + size, err := strconv.Atoi(sizeStr) + if err != nil { + return err + } + + _, err = conn.Write([]byte("READY\n")) + if err != nil { + return err + } + + file, err := os.Create(destination) + if err != nil { + return err + } + defer file.Close() + + buffer := make([]byte, 1024) + received := 0 + for received < size { + n, err := conn.Read(buffer) + if err != nil && err != io.EOF { + return err + } + received += n + _, _ = file.Write(buffer[:n]) + } + return nil +} diff --git a/tools/dbg/push.go b/tools/dbg/push.go new file mode 100644 index 00000000..748e1a6b --- /dev/null +++ b/tools/dbg/push.go @@ -0,0 +1,47 @@ +package main + +import ( + "fmt" + "io" + "os" + "strings" +) + +func push(args []string) error { + if len(args) != 2 { + return fmt.Errorf("push takes exactly two arguments") + } + source := args[0] + destination := args[1] + + file, err := os.Open(source) + if err != nil { + return err + } + defer file.Close() + + info, err := file.Stat() + if err != nil { + return err + } + size := info.Size() + + if _, err := send(fmt.Sprintf("upload %s %d", destination, size)); err != nil { + return err + } + + if _, err := io.Copy(conn, file); err != nil { + return err + } + + resp, err := receive() + if err != nil { + return err + } + + if strings.TrimSpace(resp) != "OK" { + return fmt.Errorf("upload failed: %s", resp) + } + fmt.Printf("%s uploaded successfully!", destination) + return nil +} diff --git a/tools/dbg/shell.go b/tools/dbg/shell.go new file mode 100644 index 00000000..1976b791 --- /dev/null +++ b/tools/dbg/shell.go @@ -0,0 +1,13 @@ +package main + +import ( + "io" + "os" +) + +func shell(args []string) error { + go io.Copy(os.Stdout, conn) + go io.Copy(conn, os.Stdin) + + select {} +}