QNX 7.0.0开发总结

1 QNX编译
1.1 基本概念
QNX可以直接使用Linux Makefile编译库和二进制,在Makefile文件中指定CC=aarch64-unknown-nto-qnx7.0.0-g++,或者CC=x86_64-pc-nto-qnx7.0.0-g++,保存退出后,运行source /qnx_sdk_path/qnxsdp-env.sh,然后再运行make即可。

QNX官方不建议直接使用xxx-g++,而是使用q++ -Vxxx,q++通过选项-Vxxx找到对应的g++编译器,如何获取xxx,可以使用q++ -V查询。并且只能将选项-Vxxx加到C语言的CFLAGS或者C++语言的CXXFLAGS中,不能加到其它地方,否则编译会出现各种奇怪的错误。

在q++编译中宏-D_QNX_SOURCE的作用是包括POSIX的头文件,包括数据类型、宏声明、库函数等。如果CXXFLAGS只加了-std=C++11,但没有-D_QNX_SOURCE,就算是包含了头文件unistd.h等,还是无法使用POSIX相关库函数和声明等。C++11先前被称作C++0x。

需要注意的是QNX下Makefile链接线程库使用-pthread而不是Linux风格的-lpthread,而其它的库仍然和Linux一样,需要添加前缀-l,例如-lcrypto。

source /qnx_sdk_path/qnxsdp-env.sh
x86_64-pc-nto-qnx7.0.0-gcc \
-o tcp_server tcp_server.c -lsocket

1.2 showcase
CC = q++
.PHONY: clean

OBJS = src/main.o
CFLAGS = \
        -I./include \
        -Vgcc_ntox86_64_cxx
LDFLAGS = -pthread -lcrypto

# compile every cpp file to object
%.o: %.cpp
        $(CC) $(CFLAGS) -c $^ -o $@
# link all of the objects to hello
hello: $(OBJS)
        $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) \
            -o $@
clean:
        rm -rf $(OBJS)
        rm -rf hello

1.3 QNX proprietary Makefile
variant:
g-le: A debugging version of a little-endian executable
o-le: executable
a-le: static library, a means archive
so-le: shared library

mkdir my_project
cd my_project
mkdir inc
mkdir src
touch common.mk
touch Makefile
addvariant aarch64 o-le

le: little endian
PINFO: package info

1.4 build_files
xxx.build.tmpl:一般一个分区一个build文件。Because .build file does not support MACRO, could use Linux filepp command to replace MACRO.
filepp -DMACRO_TEST=${MACRO_TEST} \
my.build > my.build_new

on -R0x7 pipe &
-R:表示CPU掩码,亲和性;0x7 = 0111,CPU0、CPU1、CPU2,不包含CPU3

mkifs xxx.build.tmpl xxx.ifs
dumpifs xxx.ifs
/proc/boot

2 进程和sepol
2.1 进程优先级
QNX的线程优先级,是一个0 - 255的数字,数字越大优先级越高。所以,优先级0是内核中的idle线程;同时,优先级64是一个分界岭,就是说,优先级1 - 63是非特权优先级,一般用户都可以用,而64 - 255必须是有root权限的线程才可以设。QNX进程或者线程刚创建时的优先级是10。
procnto-smp-instr: Instrumented

2.2 QNX secpol
secpol是QNX 7.0才引入的,类似于Android sepolicy,运行on命令时指定参数-T xxx_service_t即可。
编译时需要将SDK 7.0中的aarch64le/bin/secpol和aarch64le/bin/secpolmonitor(不能与secpolgenerate同时运行,因为这2个命令用到同一个目录,运行有冲突)集成到image中。

allow_attach: resmgr_attach()
allow_link: pathmgr_symlink()

__SECURE_BOOT_SECPOL__
allow_attach io_pkt_v6_hc_t {
    /path/to/socket_name
};

/proc/boot/secpol.bin
secpolmonitor -pasno /tmp/secpol.out &
secpolmonitor -pasno /tmp/secpol.out \
-S subrangedAble &
genpol

2.3 列出所有的进程加载了哪些so库
pidin -F "%O"

3 console
3.1 Android vdev console
# x86 vdev ser8250
# aarch64 ttyAMA0
# fdtdump, qnx Configuring guests
vdev vdev-pl011.so
    loc 0x1c090000
    intr gic:37

3.2 命令
To attach to an existing session:
dtach -a <socket> <options>

Detach from a session
In an attached session, type Ctrl+\

QVM <-> dtach server <-> dtach client <-> QNX shell
ptsname slave (QNX QVM) <-> /dev/ptmx master (QNX dtach, other node by QNX) <-> /tmp/console (QNX dtach, unix-domain socket server) <-> dtach client (dtach -a /tmp/console) <-> QNX shell

3.3 dtach showcase
server:
on -T xxx_t -u 0:0 \
-d /usr/bin/dtach \
-n /path/to/socket_name \
-r winch qvm @/vm/images/linux-la.config

-T apply secpol type to dtach
-u uid:gid
-d daemon
-n new session
-r redraw, winch means windows change

client:
dtach -a /path/to/socket_name
-a attach

3.4 slogger
https://github.com/christianzeroc/openqnx
slog2info是slogger2的客户端。

4 Block
4.1 Block设备
/dev/hd0t12 - t表示type,12表示FAT32分区
/dev/hd1t6 - t表示type,6表示文件系统类型FAT
/fs/usb0
fdisk /dev/hd1 show
dinit:disk initialization

[25-Jan-2022]
mount block device as read write, find command from .build file.
mount -tqnx6 -u -w /dev/xxx /xxx

4.2 Android和QNX共享数据
QNX ->
ls /dev/hd0.*
mkdosfs /dev/hd0.xxx
mount -t dos /dev/hd0.xxx /mnt

Android ->
ls -al /dev/block/by-name/
mount -t vfat -o sync,rw /dev/block/vda17 /mnt/share

5 Display
5.1 keyboard
vdev vdev-virtio-input.so

/usr/share/keyboard/US_101.kbd
slog2info  | grep screen
slog2info  | grep qvm

5.2 screen
#include <screen/screen.h>
screen_set_event_property_iv()
iv: integer value
cv: char value

6 Network
6.1 FreeBSD
QNX network commands all come from BSD family.
ral0: devnp-ral.so, Ralink
wm0: devnp-e1000.so, wiseman, name comes from FreeBSD

nw_dll_syms
https://github.com/ownmac/qnx_drv/tree/master/hardware/devnp/e1000

6.2 Basic Commands
io-pkt-v6-hc: hardware crypto, crypto is OpenSSL library.

# TUNnel: peer=/dev/qvm/la/la_to_host,\
# bind=/dev/vdevpeer/vp0,
on io-pkt-v6-hc -d vdevpeer-net \
peer=/dev/qvm/la/la_to_host,\
bind=/dev/vdevpeer/vp0,\
mac=bbbbbbbbbbbb

# mount -T io-pkt -o <options>
# options for network driver
# unload eth0 driver
# call driver xxx_detach()
ifconfig eth0 destroy

ifconfig bridge0 create
ifconfig bridge0 destroy
brconfig bridge0 delete eth0

6.3 iptables NAT for hypervisor
PREROUTING:DNAT专用。
POSTROUTING:SNAT专用。
MASQUERADE:SNAT转换时,如果--to-source的地址经常变化,那么就无法在iptables命令中固定,譬如路由器WAN口上的IP地址,内网设备通过WAN口访问外网时,只要指定使用MASQUERADE参数,iptables就会统一将内网设备的IP地址替换为路由器WAN口的IP地址。
Figure 6-1 NAT chain

vp0: 192.168.0.98 (QNX veth)
eth0: 192.168.0.99 (Android veth)
eth1: 192.168.5.99 (Android USB Ethernet)

Because PC could not get QNX vp0 MAC, so use the following commands for NAT, PC client should connect eth1 IP.
# client -> eth1 -> eth0 -> vp0 -> server
iptables -I FORWARD 1 -i eth1 -o eth0 -j ACCEPT
iptables -I FORWARD 1 -i eth0 -o eth1 -j ACCEPT
iptables -t nat -A PREROUTING -i eth1 -j DNAT --to-destination 192.168.0.98
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
echo 1 > /proc/sys/net/ipv4/ip_forward

6.4 QNX sshd
passwordless登陆,QNX Neutrino 6.6.0用户密码加密默认算法是SHA-512,1000轮计算,并附带16字节的盐值。
1) Windows puttygen产生公匙和私匙.ppk
2) Windows WinSCP导入私匙.ppk
3) 将Windows puttygen产生的公匙转换为QNX的格式
QNX shell:
ssh-keygen -i -f win_rsa.pub > /path/to/authorized_keys
4) /path/to/sshd_config
StrictModes no
PasswordAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile /path/to/authorized_keys

6.5 Windows as ssh server
1) Install ssh server for Win10: BvSshServer (original name is WinSSHD)
https://www.bitvise.com/ssh-server-download
Bitvise SSH Server installer

a) Personal Edition
b) Open easy settings
c) Server settings
d) Virtual accounts
- Virtual account password
- test/888888
- Save changes
e) Start Server

2) 在QNX环境下,将Windows下的文件复制到QNX系统中:
scp -S /path/to/ssh virtual_account_name@192.168.3.181:/d:/test/config.ips  /tmp
如果ssh不在/usr/bin/ssh下,需要给scp指定-S参数,否则scp执行失败。

6.6 QNX Momentics Debug
1) QNX shell
Run qconn, default qconn port: 8000
Enable bridge or NAT

2) Windows Momentics IDE
[Windows][Perspective][Open Perspective][QNX System Information]
[Target Navigator][New QNX Target]

Configure IP and 8000, then Momentics will connect to QNX automatically.

6.7 eAVB
ptpd-avb: gPTP
ptpd: IEEE1588 v2

6.8 QNX adb test
1) Android
ip route get <X.Y.Z.5>
ip rule add to X.Y.Z.0/24 lookup main pref 9999

setprop service.adb.tcp.port 5555
stop adbd
start adbd
iptables-save | grep 5555
iptables -A INPUT -i eth0 -p tcp -m tcp --dport 5555 -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp -m tcp --dport 5555 -j ACCEPT
2) QNX
mount block device as read write, find command from .build file.
mount -tqnx6 -u -w /dev/xxx /xxx
Copy libnbutil.so.1 to /path/to/lib as LD_LIBRARY_PATH shown.
route get <ANDROID_IP>
adb connect <ANDROID_IP>
adb shell

7 x86 USB
7.1 FreeBSD
QNX USB API and umass (src/sys/dev/usb/umass.c) all come from BSD family.
FreeBSD SCSI software architecture is called CAM (Common Access Method), it developed by Future Domain and other SCSI vendors. Linux has little support for a SCSI CAM system yet (mainly for booting from hard disk). CAM even supports target mode, so one could disguise ones computer as a peripheral hardware device (e.g. for a small SCSI net).

7.2 usblauncher_otg
client communicates with io-usb through /dev/io-usb/io-usb
pps: Persistent Publish/Subscribe
/pps/qnx/device/usb_ctrl
usbd_alloc(): /memory/below4G, pidin syspage=asinfo (Address Space Information)

pidin -p qvm irqs
while true; do /bin/slay qvm; \
if [ $? -ne 1 ]; then break; fi; \
done

io-usb-otg -d xhci
devb-umass cam pnp
usb -vvvv

slay devb-umass

7.3 USB PHY Tunning
1) QNX设备地址映射函数
#include <sys/mman.h>
#include <sys/neutrino.h>
ThreadCtl(_NTO_TCTL_IO, 0); 
void *ptr = mmap_device_memory(0,
    len,
    PROT_READ|PROT_WRITE| \
    PROT_NOCACHE,
    0,
    0xb8000);
if (ptr == MAP_FAILED) {}

2) in32_x86 and out32
# get xHCI BAR0 in QNX, skip bit0-bit3 of BAR0
pci-tool -d 0:21:0 --read=CFG:0x10

# APL (Gen9, A39X0) 8-port MPH xHCI PORTSC1
in32_x86 <addr from the last step + 0x480>

7.4 x86 xHCI透传
APL (Gen9, A39X0) 8-port MPH xHCI透传给Android后,尽管在QNX下可以使用in32_x86命令和函数mmap_device_memory()读写xHCI寄存器,但是由于IOMMU中仍然有xHCI的DMAR和INTR配置,所以即使卸载Android端xHCI驱动,加载QNX端xHCI驱动,也不会工作;要想让xHCI在QNX下可以工作,需要删除xHCI在IOMMU中的DMAR和INTR配置。

8 x86 GPIO
8.1 P2SB
PCH(
Platform Controller Hub)上大部分设备可以通过PCIe或IO方式访问,但PCH上部分设备需要访问PCH的私有空间,这部分空间通过P2SB(Primary to SideBand)的SBREG_BAR寄存器映射到内存空间,这段空间被称为PCRPCH Private Configuration Space Register。每个设备对应一个PortID,PortID表示设备在PCR空间的偏移量,再加上寄存器偏移可以获取寄存器的地址。

8.2 P2SB GPIO
x86下GPIO寄存器位于PCH的私有空间。GPIO被分组,每组对应一个PCR的PortID。GPIO community和PortID的对应关系如下所示。
SouthWest: 0xC0
NorthWest: 0xC4
North: 0xC5
West: 0xC7

每个community的每个GPIO有2个寄存器,分别是PADCFG0(偏移0)和PADCFG1(偏移4),2个寄存器占用8个字节的地址,所以计算某个GPIO 2个寄存器的绝对地址方法如下,其中PortID是每个GPIO community在PCR空间的偏移量。
基地址pad_regs = 0xf8000000(P2SB bar0) + (PortID << 16) + 0x500(read from PADBAR);
某个GPIO padcfg0的绝对地址 = pad_regs + PADCFG0 + 在bank内的GPIO编号 x 8;
某个GPIO padcfg1的绝对地址 = pad_regs + PADCFG1 + 在bank内的GPIO编号 x 8;

每个community的32个GPIO公用2个寄存器,分别是GPI_IS(GPI Interrupt Status)和GPI_IE(GPI Interrupt Enable),2个中断相关寄存器的绝对地址计算方法如下,其中PortID是每个GPIO community在PCR空间的偏移量。
基地址regs = 0xf8000000(P2SB bar0) + (PortID << 16);
某个GPIO GPI_IS的绝对地址 = regs + 0x100(GPI_IS)+ 在bank内的GPIO编号 / 32;
某个GPIO GPI_IE的绝对地址 = regs + 0x110(GPI_IE)+ 在bank内的GPIO编号 / 32;


/sys/class/gpio/gpiochip434/label
跟dts或者ACPI dsl文件对应上,是哪一组

gpiochip434 - North
gpiochip357 - Northwest
gpiochip310 - West
gpiochip267 - Southwest

9 Abbreviations
APIC:读作ei pic
APS:adaptive partitioning
CAM:UNIX/QNX SCSI Common Access Methods
dtach:detach
hogs:List the processes that are hogging the CPU
IFS:Image File System,QNX系统镜像
IPL:Image Program Loader,bootloader程序
mbuf: Unix TCP/IP message buffer
OCP:Open Core Protocol
OpenUSBDI: Open USB Driver Interface
P2SB:Primary to SideBand
pbuf: lwip packet buffer
pidin:类似于Linux ps,也可以执行pidin arg
PPS: QNX Persistent Pusblish/SubScribe
QNX: Quick UNIX
slay <pid>:kill进程
slm: System Launch and Monitor
smmuman:IOMMU/SMMU Manager
ttyAMA: ARM AMBA PL011
vp0: vdevpeer

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/347018.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React+TS前台项目实战(四)-- layout整体布局搭建

文章目录 前言一、Layout组件代码注释说明二、Content全局组件注释说明三、Header基础布局组件1. Header父级组件注释说明2. NavMenu导航子组件详细说明 四、效果展示总结 前言 本文主要讲Layout整体布局的构建以及全局内容盒子Content组件的使用。还包括了导航栏组件的基本封…

实现开源可商用的 ChatPDF RAG:密集向量检索(R)+上下文学习(AG)

实现 ChatPDF & RAG&#xff1a;密集向量检索&#xff08;R&#xff09;上下文学习&#xff08;AG&#xff09; RAG 是啥&#xff1f;实现 ChatPDF怎么优化 RAG&#xff1f; RAG 是啥&#xff1f; RAG 是检索增强生成的缩写&#xff0c;是一种结合了信息检索技术与语言生成…

python之点云数据读取与可视化

1、前言 将文件中点云数据进行读取进来&#xff0c;并进行数据处理&#xff0c;将处理后的点云数据进行可视化显示&#xff0c;是非常常见的操作。本博客介绍如何将文本形式的点云数据读取进来&#xff0c;并进行可视化展示。 2、点云可视化 点云可视化即将点云数据在三维空间…

亚马逊竞品分析之如何查找竞品

初选之后,要对产品进行竞品分析,查找竞品的方法: 1.Best Seller榜单查找 进入到该类目的BS榜单去找跟你选中的产品的竞品 看完BS榜单会找出一部分竞品 这个找相似也可以点击,是插件的一个以图搜图的功能,不过有的时候不太好使,某些同款产品可能搜不到。 Edge浏览器搭…

第7章 用户输入和 while 循环

第7章 用户输入和 while 循环 7.1 函数 input()的工作原理7.1.1 编写清晰的程序7.1.2 使用 int()来获取数值输入7.1.3 求模运算符 7.2 while 循环简介7.2.1 使用 while 循环7.2.2 让用户选择何时退出7.2.3 使用标志7.2.4 使用 break 退出循环7.2.5 在循环中使用 continue7.2.6 …

【Vue】Vuex概述

文章目录 一、使用场景二、优势三、注意 官网&#xff1a;https://vuex.vuejs.org/zh/ Vuex 是一个 Vue 的 状态管理工具&#xff0c;状态就是数据。 工具可以直接理解成插件 大白话&#xff1a;Vuex 是一个插件&#xff0c;可以帮我们管理 Vue 通用的数据 (多组件共享的数据)…

【Affine / Perspective Transformation】

文章目录 仿射变换介绍仿射变换 python 实现——cv2.warpAffine透视变换透视变换 python 实现——cv2.warpPerspective牛刀小试各类变换的区别与联系仿射变换和单应性矩阵透视变换和单应性矩阵 仿射变换介绍 仿射变换&#xff08;Affine Transformation&#xff09;&#xff0…

适配器模式和装饰器模式

文章目录 适配器模式1.引出适配器模式1.多功能转换插头2.基本介绍3.工作原理 2.类适配器1.基本介绍2.类图3.代码实现1.Voltage220V.java2.Voltage5V.java3.VoltageAdapter.java4.Phone.java5.Client.java6.结果 4.类适配器的注意事项 3.对象适配器1.基本介绍2.使用对象适配器改…

C51单片机 串口打印printf重定向

uart.c文件 #include "uart.h"void UartInit(void) //4800bps11.0592MHz {PCON | 0x80; //使能波特率倍速位SMODSCON 0x50; //8位数据,可变波特率。使能接收TMOD & 0x0F; //清除定时器1模式位TMOD | 0x20; //设定定时器1为8位自动重装方式TL1 0xF4; //设…

明天15点!如何打好重保预防针:迎战HVV经验分享

在当今数字化时代&#xff0c;网络攻击日益猖獗&#xff0c;各行各业面临的网络安全威胁不断升级。从钓鱼邮件到复杂的APT攻击&#xff0c;网络犯罪分子的手法层出不穷&#xff0c;给各行各业的信息安全带来了前所未有的挑战。 在这样的背景下&#xff0c;"HVV行动"应…

那些年我看过的技术书(持续更新,大佬的成长之路)

作为一个技术人啊&#xff0c;要学会多看书&#xff0c;发展自己。哦也&#xff01;你可以不关注&#xff0c;就把文章点个收藏吧&#xff0c;万一以后想看书了呢&#xff1f; 网络安全 CTF篇 入门篇 《极限黑客攻防&#xff1a;CTF赛题揭秘》 Web篇 Reserve篇 《IDApro…

ON DUPLICATE KEY UPDATE 子句

ON DUPLICATE KEY UPDATE 是 MySQL 中的一个 SQL 语句中的子句&#xff0c;主要用于在执行 INSERT 操作时处理可能出现的重复键值冲突。当尝试插入的记录导致唯一索引或主键约束冲突时&#xff08;即试图插入的记录的键值已经存在于表中&#xff09;&#xff0c;此子句会触发一…

virtual box安装invalid installation directory

问题原因 看官方文档Chapter 2. Installation Details 第2.1.2所示&#xff0c;安装目录需要满足两个条件&#xff1a; 一是&#xff1a;需要安装目录的所有父目录都要满足以下访问控制条件 Users S-1-5-32-545:(OI)(CI)(RX) Users S-1-5-32-545…

【Python列表解锁】:掌握序列精髓,驾驭动态数据集合

文章目录 &#x1f680;一、列表&#x1f308;二、常规操作&#x1f4a5;增&#x1f4a5;删&#x1f4a5;改&#x1f4a5;查 ⭐三、补充操作 &#x1f680;一、列表 列表是一个能够存储多个同一或不同元素的序列 列表&#xff1a;list ---- [] 列表属于序列类型&#xff08;容器…

ES升级--05--快照生成 和备份

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 备份ES数据1.关闭集群自动均衡2.执行同步刷新3.停止集群节点的Elasticsearch服务4.修改Elasticsearch配置文件&#xff0c;开启快照功能&#xff0c;配置仓库目录为…

axure9设置组件自适应浏览器大小

问题&#xff1a;预览时不展示下方的滚动条 方法一&#xff1a;转化为动态面板 1.在页面上创建一个矩形 2.右键-转化为动态面板 3.双击进入动态面板设置 4.设置动态面板矩形的颜色 5.删除原来的矩形 6.关闭动态面板&#xff0c;点击预览 7.此时可以发现底部没有滚动条了 方法…

Java进阶_多态特性

生活中的多态 多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口&#xff0c;使用不同的实例而执行不同操作&#xff0c;如图所示&#xff1a; 现实中&#xff0c;比如我们按下 F1 键这个动作&#xff0c;同一个事件发生在不同的对象上会产生不同的结果。…

ElasticSearch学习笔记之三:Logstash数据分析

第3章 Logstash数据分析 Logstash使用管道方式进行日志的搜集处理和输出。有点类似*NIX系统的管道命令 xxx | ccc | ddd&#xff0c;xxx执行完了会执行ccc&#xff0c;然后执行ddd。 在logstash中&#xff0c;包括了三个阶段: 输入input --> 处理filter&#xff08;不是必须…

Android 代码打印meminfo

旨在替代adb shell dumpsys meminfo packageName&#xff0c;在log打印meminfo&#xff0c;以便分析内存情况 ActivityManager.MemoryInfo memoryInfo new ActivityManager.MemoryInfo(); activityManager.getMemoryInfo(memoryInfo); long totalMemory Runtime.getRuntime(…

6、后端项目初始化

打开idea后&#xff0c; New Project &#xff0c;用Maven构建 Spring Boot 项目 点击Next后&#xff1a;先勾选两个基本的依赖&#xff0c;后面再手动添加其它需要的依赖 Spring Web: 表示是一个web应用程序 Lombok&#xff1a;写实体类的时候添加Data注解后就会自动加上g…