kindle7插件开发笔记[1]-在折腾中入门
写的确实很乱,时间跨度很大,可以当做笔记看
越狱
[https://bookfere.com/post/98.html]
自制插件
根据测试,为自己的插件项目新建一个文件夹
如app1,目录结构
app1
-menu.json
-config.xml
-app1.sh
-app(unix可执行文件)
其中app1.sh为linux的shell脚本
menu.json:
{
"items": [
{"name": "app1", "priority": 1, "action": "app1.sh"}
]
}
要改什么字段显然了
config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<extension>
<information>
<name>app1</name>
<version>2.6</version>
<author>qsBye</author>
<id>app1</id>
</information>
<menus>
<menu type="json" dynamic="true">menu.json
</menu>
</menus>
</extension>
app1.sh:
#!/bin/sh
EXTENSION=/mnt/us/extensions/my_app1
DPI=`cat /var/log/Xorg.0.log | grep DPI | sed -n 's/.*(\([0-9]\+\), [0-9]\+).*/\1/p'`
#use different layouts for high resolution devices
if [ ${DPI} -gt 290 ]; then
PARAM="-l ${EXTENSION}/layouts/keyboard-300dpi.xml"
elif [ ${DPI} -gt 200 ]; then
PARAM="-l ${EXTENSION}/layouts/keyboard-200dpi.xml"
fi
export TERM=xterm TERMINFO=${EXTENSION}/vte/terminfo
${EXTENSION}/app1 ${PARAM} "$@"
分割线2022-2-22更新
1.查到的库存储地址
/lib
/usr/lib
2.编译器应该是arm-linux=gnueabihf
3.编译静态库.a就不用动态库了,静态库包含进程序内
4./lib/libc.so文件实现的功能
ANSI C 函数库是基本的 C 语言函数库,包含了 C 语言最基本的库函数。这个库可以根据头文件划分为 15 个部分,其中包括:
<ctype.h>:包含用来测试某个特征字符的函数的函数原型,以及用来转换大小写字母的函数原型;
<errno.h>:定义用来报告错误条件的宏;
<float.h>:包含系统的浮点数大小限制;
<math.h>:包含数学库函数的函数原型;
<stddef.h>:包含执行某些计算 C 所用的常见的函数定义;
<stdio.h>:包含标准输入输出库函数的函数原型,以及他们所用的信息;
<stdlib.h>:包含数字转换到文本,以及文本转换到数字的函数原型,还有内存分配、随机数字以及其他实用函数的函数原型;
<string.h>:包含字符串处理函数的函数原型;
<time.h>:包含时间和日期操作的函数原型和类型;
<stdarg.h>:包含函数原型和宏,用于处理未知数值和类型的函数的参数列表;
<signal.h>:包含函数原型和宏,用于处理程序执行期间可能出现的各种条件;
<setjmp.h>:包含可以绕过一般函数调用并返回序列的函数的原型,即非局部跳转;
<locale.h>:包含函数原型和其他信息,使程序可以针对所运行的地区进行修改。
地区的表示方法可以使计算机系统处理不同的数据表达约定,如全世界的日期、时间、美元数和大数字;
<assert.h>:包含宏和信息,用于进行诊断,帮助程序调试。
上述库函数在其各种支持 C 语言的 IDE 中都是有的。
5.编译时链接函数库(编译时,目录是宿主机不是客户机)
'''
-Iinclude_dir : 在头文件中搜索路径列表中添加include_dir
-Llibpath : 指定链接库搜索路径,如库都放在/prj/libs/下面,则-L/prj/libs
1)ELF可执行文件中动态段中DT_RPATH所指定的路径。即在编译目标代码时, 对gcc加入链接参数“-Wl,-rpath”指定动态库搜索路径,eg:gcc -Wl,-rpath,/home/arc/test,-rpath,/lib/,-rpath,/usr/lib/,-rpath,/usr/local/lib test.c
2)环境变量LD_LIBRARY_PATH 指定的动态库搜索路径
3)/etc/ld.so.cache中所缓存的动态库路径,这个可以通过先修改配置文件/etc/ld.so.conf中指定的动态库搜索路径,然后执行ldconfig命令来改变。
4)默认的动态库搜索路径/lib
5)默认的动态库搜索路径/usr/lib
'''
gcc -L/lib_client -l/include_client
6.客户机加入库搜索路径
export LD_LIBRARY_PATH=
7.用到的库及依赖
libpng,依赖{zlib}
libx11,依赖
libc
8.kindle显示图片命令eips -g /mnt/us/w.png(假设图片在电脑显示的盘符的根目录)
kindle刷新显示 eips ''
(https://wiki.mobileread.com/wiki/Eips)
开启和关闭wifi命令
lipc-set-prop com.lab126.cmd wirelessEnable 1
lipc-set-prop com.lab126.cmd wirelessEnable 1
kindle定时任务(定时执行date命令)
vim /etc/crontab/root
0 7 * * * date 保存,然后重启kindle
kindle阻止屏幕休眠
方法1)搜索栏输入~ds然后回车(https://bookfere.com/post/150.html)
方法2)lipc-set-prop -i com.lab126.powerd preventScreenSaver 1
分割线2022-2-23更新=
9.ldd命令提示not a dynamic executable
ld这个命令缺失库不能完整运行,
用readelf
实质是编译时没有指定使用的动态库
交叉编译时一定要-l和-L指定库,头文件用-I指定(有时可以用本地的)
readelf -l 可执行文件 | grep ld-linux
10.kindle著名插件kterm(终端模拟器)
https://github.com/bfabiszewski/kterm
http://www.fabiszewski.net/kindle-terminal/
学习这个有利于我们自制kindle插件
11.查看程序的编译器版本
readelf xx -p .comment
也可以用 objdump -s --section=.comment xx
(https://blog.csdn.net/yanhe156/article/details/80528589?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2aggregatepagefirst_rank_ecpm_v1~rank_v31_ecpm-4-80528589.pc_agg_new_rank&utm_term=linux+怎么查看编译器&spm=1000.2123.3001.4430)
12.使用xmake工具来管理跨平台编译
https://xmake.io/#/
13.查看处理器信息
cat /proc/cpuinfo
getconf LONG_BIT查看位数
uname -a
14.柳暗花明又一村,c语言编译的文件总是无法执行,报错not a dynamic executable,ldd查询库链接发现有问题
=>换用golang继续,go语言支持armv7l平台。
实测kindle上可以运行hello world程序!!!
cd /usr/local/Cellar/go/1.16.6/libexec/src
mkdir hello
touch hello.go
go mod init example/hello
vim hello.go
'''
package main
import "fmt"
func main() {
fmt.Println("Hello, world.")
}
'''
编译命令GOOS=linux GOARCH=arm go build
运行结果⬇️,激动啊,研究了几十个小时!
运行ldd命令还是会提示not a dynamic executable但是这不影响程序运行!
参考(https://www.learnhard.cn/articles/980.html)
===分割线-=2022-2-24=
TODO:golang通过framebuffer修改显示内容,绘图,显示png图片
关键的第一步
编译给ubuntu(amd64),编译命令GOOS=linux GOARCH=amd64 go build
成功显示出了信息,但是png decode failed.
为kindle编译
set.go
package main
/***********
作者:红猎人
***********/
import (
"os"
"syscall"
"fmt"
"unsafe"
"image/png"
//"image/color"
"image"
"bytes"
/*
"image/png"
"bytes"
*/
)
var (
FBIOGET_VSCREENINFO = 0x4600
)
type fbBitfield struct {
offset uint32 /* beginning of bitfield */
length uint32 /* length of bitfield */
msb_right uint32 /* != 0 : Most significant bit is */
}
type fbVarInfo struct {
xres uint32 /* visible resolution */
yres uint32
xres_virtual uint32 /* virtual resolution */
yres_virtual uint32
xoffset uint32 /* offset from virtual to visible */
yoffset uint32 /* resolution */
bits_per_pixel uint32 /* guess what */
grayscale uint32 /* 0 = color, 1 = grayscale, */
/* >1 = FOURCC */
red fbBitfield /* bitfield in fb mem if true color, */
green fbBitfield /* else only length is significant */
blue fbBitfield
transp fbBitfield /* transparency */
nonstd uint32 /* != 0 Non standard pixel format */
activate uint32 /* see FB_ACTIVATE_* */
height uint32 /* height of picture in mm */
width uint32 /* width of picture in mm */
accel_flags uint32 /* (OBSOLETE) see fb_info.flags */
/* Timing: All values in pixclocks, except pixclock (of course) */
pixclock uint32 /* pixel clock in ps (pico seconds) */
left_margin uint32 /* time from sync to picture */
right_margin uint32 /* time from picture to sync */
upper_margin uint32 /* time from sync to picture */
lower_margin uint32
hsync_len uint32 /* length of horizontal sync */
vsync_len uint32 /* length of vertical sync */
sync uint32 /* see FB_SYNC_* */
vmode uint32 /* see FB_VMODE_* */
rotate uint32 /* angle we rotate counter clockwise */
colorspace uint32 /* colorspace for FOURCC-based modes */
reserved [4]uint32 /* Reserved for future compatibility */
}
func main() {
//fb, err := os.Open("/dev/graphics/fb0")
///Users/workspace/Desktop/kindle7开发/2022-2-23/ubuntu/fb0
fb, err := os.Open("/dev/fb0")
if err != nil {
panic("can't open file /dev/fb0")
}
defer fb.Close()
fmt.Printf("file open %v \n", fb.Fd())
var varInfo fbVarInfo
_,_,errno := syscall.RawSyscall(syscall.SYS_IOCTL, fb.Fd(), uintptr(FBIOGET_VSCREENINFO), uintptr(unsafe.Pointer(&varInfo)))
if errno != 0 {
fmt.Println(errno)
panic("can't ioctl ... ")
}
fmt.Printf("width = %d height = %d\n", varInfo.xres, varInfo.yres)
fmt.Printf("xoffset = %d yoffset = %d\n", varInfo.xoffset, varInfo.yoffset)
fmt.Printf("depth = %d\n", varInfo.bits_per_pixel/8)
// func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error)
/*描述符fd,
offset参数指定了从文件区域中的哪个字节开始映射,它必须是系统分页大小的倍数,
flags, 映射区域的可见性:
私有映射(MAP_PRIVATE):在映射内容上发生的变更对其他进程不可见,对于文件映射来讲,变更将不会在底层文件上发生。
共享映射(MAP_SHARED):在映射内容上发生的变更对所有共享同一个映射的其他进程都可见,对于文件映射来讲,变更将会发生在底层的文件上。
prot,映射区域的访问权限,可选项包括 READ/WRITE/EXEC/NONE。
如果映射是私有的,那么不修改被映射的文件。
*/
bpp := varInfo.bits_per_pixel / 8
size := varInfo.xres * varInfo.yres * bpp
offset := varInfo.xoffset * bpp + varInfo.xres * bpp * varInfo.yoffset
mapsize := size + offset
fmt.Printf("mapsize = %d\n", mapsize)
data, err := syscall.Mmap(int(fb.Fd()), 0, int(mapsize) , syscall.PROT_READ, syscall.MAP_PRIVATE)
if err != nil {
panic("map failed ...")
}
/*defer :它可以在函数返回前执行一些操作,一旦mmap()被调用之后就能够关闭文件描述符了,而不会对映射产生任何影响。*/
defer syscall.Munmap(data)
// save as png image.
//
//func Encode(w io.Writer, m image.Image) error
var m image.Image
m = image.NewRGBA(image.Rect(0, 0, 2560, 1600))
screen := data[offset :]
m, err = png.Decode(bytes.NewBuffer(screen))//记得import "bytes"
if err != nil {
panic("decode fail...")
}
output, err := os.OpenFile("/home/qsbye/screenshot.png", os.O_WRONLY | os.O_CREATE, 0666)
if err != nil {
panic("can't open file /sdcard/screenshot.png")
}
defer output.Close()
err = png.Encode(output, m)
if err != nil {
panic("encoding fail...")
}
//保存fb为png图片
/*
file,err:=os.Create("framebuffer.png")
if err!=nil{
fmt.Println(err)
}
defer file.Close()
//设置图片颜色
nrgba:=image.NewNRGBA(image.Rect(0,0,2560,1600))//ubuntu的分辨率
screen:=data[offset:]
nrgba,err=png.Decode(bytes.NewBuffer(screen))
//写入文件
err=png.Encode(file,nrgba)
if err!=nil{
fmt.Println(err)
}
*/
//将png图片写入framebuffer
}
显示出了kindle的显示详细信息(颜色深度、单帧图片mapsize)
参考(https://my.oschina.net/zengsai/blog/140092这是一篇很重要的参考文献)
效果:
=======
png图片结构:
主要有数据块(Chunk Block)组成,最少包含4个数据块:
|PNG标识符|PNG数据块(IHDR)|PNG数据块(其他类型数据块)|...|PNG结尾数据块(IEND)|
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战