Exploring the Embedded Controller

Thanks, that list of comands got it to compile.

Unfortunately, using the newly built binary, the problem with segfault on each fanduty command remains.

1 Like

Ow this is odd, im fearly sure the newer kernels broke something. I need to look into this myself now too. because i sometimes used ectool to set the battery limit or change the leds so I can see what my code was doing from further away.

I get segfaults on the battery limit setting and fanduty. keyboard leds I can set fine tho. even tried the latest ectool sources as @pierce explained.

Linux framework 6.12.4-arch1-1 #1 SMP PREEMPT_DYNAMIC Mon, 09 Dec 2024 14:31:57 +0000 x86_64 GNU/Linux

older ectool

RO version:    hx30_v0.0.1-4ea1c89
RW version:    
Firmware copy: RO
Build info:    hx30_v0.0.1-4ea1c89 2023-12-11 14:15:35 runner@fv-az1124-221
Tool version:  v0.0.22543-d5b5b5008 2022-04-12 08:14:25 codeasm@

the suggested one:

RO version:    hx30_v0.0.1-4ea1c89
RW version:    
Firmware copy: RO
Build info:    hx30_v0.0.1-4ea1c89 2023-12-11 14:15:35 runner@fv-az1124-221
Tool version:  0.0.1-isolate Dec 20 2024 none
Dec 20 16:51:36 framework kernel: ectool[103705]: segfault at 0 ip 0000000000000000 sp 00007ffc024c9968 error 14 likely on CPU 0 (core 0, socket 0)
Dec 20 16:51:36 framework kernel: Code: Unable to access opcode bytes at 0xffffffffffffffd6.
Dec 20 16:51:36 framework systemd-coredump[103706]: Process 103705 (ectool) of user 0 terminated abnormally with signal 11/SEGV, processing...
Dec 20 16:51:36 framework systemd[1]: Started Process Core Dump (PID 103706/UID 0).

@SuperTux88 did you enable or disable some special configs for your build for particularly your FW laptop (or even willing to share config?) Im guessing some new security on either our side or some module you got enabled (or NOT) and thats now making me segfault?

I enabled all the drivers I need (AMD), and disabled everything I didn’t need (Intel, Nvidia, and other hardware I don’t need), so the usual I do on all PCs. I have an AMD FW13, and looking at your EC-Version it looks like you have an Intel, so I don’t think my config would be any useful for you, as it wouldn’t even boot.

But maybe it’s related to only the Intel version of the EC (hx30)? As it works for me on AMD and I think @lbkNhubert has a FW16 (2 fans?) and it’s also working there. But @D.H who also has problems also has a hx30 EC.

1 Like

Yes, my testing has been on a 16", everything seems ok. When I am back at my 13" with 11th gen Intel, I will test. That will be in a couple of days.

1 Like

Raw writes never stopped working for me. Does this battery charge limit command work for you?

sudo ./ectool raw 0x3E03 b2,w64

“64” is the hex code for 100%, 32 for 50%, etc…

1 Like

it looks like it works, but so does sudo ./ectool fwchargelimit 20
buit reading battery or temps all segfaults. I forgot if i checked these commands after i updated my FW13 bios to 3.08. @SuperTux88 thanks, yeah that wont work on Intel oops hehe. good to note indeed that this might be Intel related. I have a FW13, 12th gen i5. (which is 1 gen older then D.H

The program segfaults. Which means it produces a backtrace that points to the exact location in the source which produces the error.
If anybody can post the backtrace, created by coredumpctl info,
there is no need for blind guesswork.

1 Like
15:32:25 ✗ [codeasm@framework:/tmp/ectool/build]$ coredumpctl info
           PID: 33920 (ectool)
           UID: 0 (root)
           GID: 0 (root)
        Signal: 11 (SEGV)
     Timestamp: Sat 2024-12-21 15:32:25 CET (6s ago)
  Command Line: src/ectool battery
    Executable: /tmp/ectool/build/src/ectool
 Control Group: /user.slice/user-1000.slice/session-3.scope
          Unit: session-3.scope
         Slice: user-1000.slice
       Session: 3
     Owner UID: 1000 (codeasm)
       Boot ID: [redacted]
    Machine ID: [redacted]
      Hostname: framework
       Storage: none
       Message: Process 33920 (ectool) of user 0 terminated abnormally without generating a coredump.

Not very helpfull I think. (can we make it do a coredump and be more helpfull?)

ectool was running as root, so coredumpctl also needs to run as root to get a stacktrace.

2 Likes
Core was generated by `src/ectool battery'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000000000000000 in ?? ()
(gdb) thread apply all backtrace full

Thread 1 (Thread 0x73007ae95500 (LWP 37397)):
#0  0x0000000000000000 in ?? ()
No symbol table info available.
#1  0x00005e42b1abf2b6 in read_mapped_mem8(unsigned char) ()
No symbol table info available.
#2  0x00005e42b1ad73bd in cmd_battery(int, char**) ()
No symbol table info available.
#3  0x00005e42b1adfa01 in main ()
No symbol table info available.

(ill try enable debug and rebuild ectool? )

Yes. Can you also check the value of the global variable ec_readmem? Either through gdb or:

diff --git a/src/ectool.cc b/src/ectool.cc
index 3d6d7ed7dc71..09fde8c45a1e 100644
--- a/src/ectool.cc
+++ b/src/ectool.cc
@@ -11449,6 +11449,8 @@ int main(int argc, char *argv[])
                goto out;
        }
 
+       printf("%p\n", ec_readmem);
+
        /* Handle commands */
        for (cmd = commands; cmd->name; cmd++) {
                if (!strcasecmp(argv[optind], cmd->name)) {

In comm_init_dev() is a codepath thay may leave it uninitialized.

2 Likes
bash-5.2# src/ectool battery
(nil)
EC result 3 (INVALID_PARAM)
Segmentation fault (core dumped)

the nil isnt good I guess.

 thread apply all backtrace full

Thread 1 (Thread 0x71fde30f7500 (LWP 45517)):
#0  0x0000000000000000 in ?? ()
No symbol table info available.
#1  0x00005b3fba7652b6 in read_mapped_mem8 (offset=36 '$') at /tmp/ectool/src/ectool.cc:481
        ret = 1
        val = 182 '\266'
        __func__ = "read_mapped_mem8"
#2  0x00005b3fba77d3bd in cmd_battery (argc=1, argv=0x7ffcb6916dc0) at /tmp/ectool/src/ectool.cc:8161
        batt_text = "\270m\221\266\374\177\000"
        rv = 248
        val = 1
        e = 0x8000000f8 <error: Cannot access memory at address 0x8000000f8>
        index = 0
        flags = 186 '\272'
#3  0x00005b3fba785a1f in main (argc=2, argv=0x7ffcb6916db8) at /tmp/ectool/src/ectool.cc:11457
        cmd = 0x5b3fba79f4c0 <commands+96>
        dev = 0
        interfaces = -1
        i2c_bus = -1
        device_name = "cros_ec", '\000' <repeats 33 times>
        vid = 6353
        pid = 20514
        rv = 1
        parse_error = 0
        e = 0x7ffcb6916c70 ""
        i = -1

Indeed.

What is the output with this?

diff --git a/src/comm-dev.cc b/src/comm-dev.cc
index f6467492f9d8..5b50f8fac281 100644
--- a/src/comm-dev.cc
+++ b/src/comm-dev.cc
@@ -284,6 +284,8 @@ int comm_init_dev(const char *device_name)
                ec_readmem = ec_cmd_readmem;
        ec_pollevent = ec_pollevent_dev;
 
+       printf("init dev %p %p %p %p\n", ec_readmem, ec_cmd_readmem, ec_readmem_dev_v2, ec_readmem_dev);
+
        /*
         * Set temporary size, will be updated later.
         */
diff --git a/src/misc_util.cc b/src/misc_util.cc
index eec8696fa5f9..a71a32f8b62a 100644
--- a/src/misc_util.cc
+++ b/src/misc_util.cc
@@ -138,6 +138,8 @@ int ec_cmd_version_supported(int cmd, int ver)
        if (ec_get_cmd_versions(cmd, &mask))
                return 0;
 
+       printf("cmd 0x%x=0x%x\n", cmd, mask);
+
        return (mask & EC_VER_MASK(ver)) ? 1 : 0;
 }

1 Like
bash-5.2# src/ectool battery
init dev (nil) 0x5705525a51eb 0x5705525a51eb 0x5705525a4e3f
EC result 3 (INVALID_PARAM)
cmd 0x600=0x1
Segmentation fault (core dumped)

coredumpctl debug (bt full):

#1  0x00005705525812b6 in read_mapped_mem8 (offset=36 '$')
    at /tmp/ectool/src/ectool.cc:481
        ret = 1
        val = 225 '\341'
        __func__ = "read_mapped_mem8"
#2  0x00005705525993bd in cmd_battery (argc=1, argv=0x7fffe149e090)
    at /tmp/ectool/src/ectool.cc:8161
        batt_text = "\000\001\000\001\000\000\000"
        rv = 248
        val = 1
        e = 0x8000000f8 <error: Cannot access memory at address 0x8000000f8>
        index = 0
        flags = 82 'R'
#3  0x00005705525a1a01 in main (argc=2, argv=0x7fffe149e088)
    at /tmp/ectool/src/ectool.cc:11455
        cmd = 0x5705525bb4c0 <commands+96>
        dev = 0
        interfaces = -1
        i2c_bus = -1
        device_name = "cros_ec", '\000' <repeats 33 times>
        vid = 6353
        pid = 20514
        rv = 1
        parse_error = 0
        e = 0x7fffe149df40 ""
        i = -1

Does it work with --interface lpc?

1 Like

No apparently it does not, (also a time ago we needed to use fwk? thats gone now tho)

# src/ectool --interface lpc battery
Missing Chromium EC memory map.
Unable to establish host communication
Couldn`t find EC

Can you provide a strace log?

1 Like

Hope this is good.
(I ran: strace -o strace.log src/ectool battery)

EDIT (after Thomas reply to bisect the driver): I reply properly if I got anything further. but for now I got this:

zcat /proc/config.gz | grep CONFIG_CROS_EC_LPC
CONFIG_CROS_EC_LPC=m
dmesg | grep cros_ec
[  +0.001371] cros_ec_lpcs cros_ec_lpcs.0: loaded with quirks 00000001
[  +0.005309] cros_ec_lpcs cros_ec_lpcs.0: Chrome EC device registered
[  +0.014682] cros_ec_lpcs cros_ec_lpcs.0: bad packet checksum 8e
[  +0.000483] cros_ec_lpcs cros_ec_lpcs.0: bad packet checksum 65
[Dec21 17:21] cros_ec_lpcs cros_ec_lpcs.0: packet too long (4 bytes, expected 0)

in my case, its a kernel module, ill try to debug/add printk and such later. im fearly new to this level of debugging. learning new things is cool. weird how checksums are bad and packet too long (LPC bus I somewhat recognize from modding my original xbox)

It’s weird. The kernel probes the device correctly for which it reads the EC id from the memmap. That works.
But then the readmem ioctl used by ectool does not read the correct EC id from the memmap. But both should go through the same functions in the kernel.
I would recommend bisecting through drivers/platform/chrome/cros_ec_lpc.c

1 Like

Actually this should not happen, you are hitting the fallback quirks,
but should hit the 11th/12th gen quirks.
What is the output of grep -r . /sys/class/dmi/id/?
(Without root to avoid leaking serial numbers)

1 Like