2020年4月2日星期四

arm_emulator: 使用slattach配置SLIP

Usage:
slattach /dev/ttyS0 -p slip -d &
ifconfig sl0 [ip] pointopoint [peer_ip] mtu 1500 txqueuelen 1000 up
route add default gw [peer_ip]

命令语法格式

slattach [-dehlLmnqv] [-c command] [-p proto] [-s speed] [tty]

命令描述

命令slattach是一个很小的程序,可用于将普通终端(“串行”)线路置于几种“网络”模式之一,从而允许你将它用于与其他计算机的点对点链接。

命令支持的选项及含义

tty串行设备的路径,如/dev/ttyS*,/dev/cua*或/dev/ptmx,用以生成新的伪tty。

[-c command]线路挂断时执行命令command。 这可用于在链接断开时运行脚本或重新建立连接。

[-d]启用调试输出。在确定给定设置无效的原因时很有用。

[-h]载体丢失时退出。这可以在/dev/tty和/dev/cua设备上运行,通过每15秒直接监视载波状态。

[-v]启用详细输出模式。在Shell脚本中非常有用。

[-q]在安静模式中进行操作,因此没有日志输出。

[-l]在/var/lock中为设备创建UUCP风格的锁文件。

[-n]等价于mesg n命令。

[-m]不要将串口初始化为8位原始模式。

[-e]初始化设备后立即退出,而不是等待线路挂断。

[-L]启用3线操作。 终端进入CLOCAL模式,禁用载波监视。

[-p proto]设置要在线路上使用的特定类型的协议。

默认设置为cslip(压缩的SLIP)。 其他可能的值是slip(正常的SLIP)、adaptive(自适应的CSLIP/SLIP)、ppp(点对点协议)、kiss(用于与AX.25分组无线电终端节点控制器进行通信的协议)。特殊参数“tty”可用于将设备恢复到正常的串行操作。 使用“ppp”模式通常不常用,因为ppp需要额外的ppp守护进程pppd在该选路上处于活动状态。 对于“kiss”连接,应使用axattach(8)程序。

[-s speed]设置特定的线路速度,而不是默认值。

注意事项如果没有给出参数,则使用当前终端线(通常是:登录设备)。 否则,尝试声明指示的终端端口,将其锁定,并打开它。

2020年3月18日星期三

arm_emulator: 通过串口建立虚拟机的网络连接

     网络是linux系统最为重要的功能之一,为此我们迫切需移植网络支持,实现一个稳定的网卡驱动和相应的外设是比较麻烦的,考虑到之前已经完善好虚拟机串口的外设,所以可以直接让以太网帧在串口上传输。虚拟机端则可以利用宿主机的tuntap虚拟网卡转发数据。
1.虚拟机实现:
    虚拟机里添加第二个串口,中断号2,实现4个虚拟网卡函数。
             .interrupt_id = 2,
            .readable = slip_tun_readable,
            .read = slip_tun_read,
            .writeable = slip_tun_writeable,
            .write = slip_tun_write,
    虚拟机串口网卡外设使用linux的tuntap虚拟网卡/dev/net/tun, 打开了两个线程,slip_out_task_proc、tun_out_task_proc,分别处理由虚拟机串口发出的数据和虚拟网卡发出的数据,使用SLIP协议进行数据帧和数据流之间的适配。由于虚拟机线程不能被阻塞,所以中间加入两个方向的fifo提高效率,利用fifo的状态实现串口readable,writeable的状态判断。

2.虚拟机内系统配置:
    内核需要开启Universal TUN/TAP device driver support 这个选项支持。
    这里有一个之前写的工具可以利用,ethoslip_tun地址),这个工具是之前调试串口WIFI模块时写的,功能是将tuntap虚拟网卡的L2数据帧使用SLIP协议封装成串口数据流。ethoslip_tun 具体流程:
tap0 <tuntap内核驱动>  /dev/net/tun  <系统调用> [ethoslip_tun<系统调用> /dev/ttySx <串口驱动> 串口外设
首先我们将ethoslip_tun下载,然后使用arm-linux-gnueabi-gcc 交叉编译,拷贝到buildroot的rootfs里,即可运行。
./ethoslip_tun /dev/ttyS1 115200&
配置IP地址:
 ifconfig tap0 10.0.0.2
 3.虚拟机外系统配置:
只需要配置IP地址即可,与虚拟机不同。
ifconfig tap0 10.0.0.1
 此时可以互相ping通:


我们尝试在虚拟机里新建一个index.php
vi index.php
<?php
phpinfo();
运行:
php -S 0.0.0.0:80
此时即可看到一个虚拟机里网页。。。😀
当然,虚拟机想要wget什么访问外网的话,只要配置宿主机的iptables,将虚拟网卡网段数据转发给物理网卡,同时虚拟机内添加默认gw。







2020年3月16日星期一

Helloworld: arm汇编

hello.s
------------------------------------
.section .data
hello:
        .ascii "hello world\n"
        len = . - hello

.section .text
.global _start
_start:
        mov r0, #1  @stdout
        ldr r1, =hello
        ldr r2, =len
        mov r7, #4
        swi #0

exit:
        mov r0, #0
        mov r7, #1
        swi #0
------------------------------------
Makefile:
------------------------------------
all:
        as hello.s -o hello.o
        ld hello.o -o hello
------------------------------------

arm_emulator: 添加了romfs外设例程

     前面版本的模拟器,只能使用一个0x00000000基地址的内存空间,文件系统是基于initramfs或者ramdisk,每次关闭模拟器,rootfs的数据全部丢失。。。
     所以我们添加一个可以操作宿主机的新外设romfs,基地址为0x10000000,其实际操作读写都使用c库访问真实的文件系统。

    {
        .mask = ~(MAX_FS_SIZE-1), //25bit
        .prefix = 0x10000000,
        .reg_base = &peripheral_reg_base.fs,
        .reset = fs_reset,
        .read = fs_read,
        .write = fs_write,
    },
内核配置:
内核需要开启CONFIG_MTD,CONFIG_MTD_PHRAM,CONFIG_MTD_BLOCK等支持。

 同时添加启动参数到设备树:
console=ttyS0 rootwait phram.phram=rootfs,0x10000000,32Mi root=/dev/mtdblock0 rw rootfstype=ext2 init=/linuxrc earlyprintk
 即可使用该外设。
https://github.com/hxdyxd/arm-emulator-linux/commit/0a00b2bb87d250a7d3bc9376b8cafc49f6e8d6fd

文件系统buildroot配置:
添加 ext2 文件系统生成

运行:
arm_emulator -m linux -f output/images/zImage.arm-emulator -r output/images/rootfs.ext2




[0]Peripheral register at 0x00000000, size 33554432
[1]Peripheral register at 0x10000000, size 33554432
Open output/images/rootfs.ext2: ok
[2]Peripheral register at 0x4001f040, size 8
[3]Peripheral register at 0x4001f020, size 8
[4]Peripheral register at 0x40020000, size 256
load mem base 0x8000, size 1996348
Uncompressing Linux... done, booting the kernel.
[    0.000000] Booting Linux on physical CPU 0x0
[    0.000000] Linux version 5.1.15 (hxdyxd@DESKTOP-ROJM0AH) (gcc version 8.3.0 (Buildroot 2020.02-g84a0769-dirty)) #1 Mon Mar 16 20:47:20 CST 2020
[    0.000000] CPU: ARM920T [41029205] revision 5 (ARMv4T), cr=00006133
[    0.000000] CPU: VIVT data cache, VIVT instruction cache
[    0.000000] OF: fdt: Machine model: hxdyxd,armemulator
[    0.000000] printk: bootconsole [earlycon0] enabled
[    0.000000] Memory policy: Data cache buffered
[    0.000000] random: get_random_bytes called from 0xc0500900 with crng_init=0
[    0.000000] Built 1 zonelists, mobility grouping on.  Total pages: 8128
[    0.000000] Kernel command line: console=ttyS0 rootwait phram.phram=rootfs,0x10000000,32Mi root=/dev/mtdblock0 rw rootfstype=ext2 init=/linuxrc earlyprintk
[    0.000000] Dentry cache hash table entries: 4096 (order: 2, 16384 bytes)
[    0.000000] Inode-cache hash table entries: 2048 (order: 1, 8192 bytes)
[    0.000000] Memory: 26948K/32768K available (3154K kernel code, 143K rwdata, 284K rodata, 1024K init, 190K bss, 5820K reserved, 0K cma-reserved)
[    0.000000] NR_IRQS: 16, nr_irqs: 16, preallocated irqs: 16
[    0.000000] armemulator-ic base address = 0xc2800040
[    0.000000] armemulator-timer base address = 0xc2802020
[    0.000000] sched_clock: 32 bits at 1kHz, resolution 1000000ns, wraps every 2147483647500000ns
[    0.000000] clocksource: timer: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1911260446275000 ns
[    0.000000] set periodic to 240000
[    0.015000] Console: colour dummy device 80x30
[    0.015000] Calibrating delay loop... 18.63 BogoMIPS (lpj=93184)
[    0.250000] pid_max: default: 4096 minimum: 301
[    0.250000] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.250000] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
[    0.265000] CPU: Testing write buffer coherency: ok
[    0.265000] Setting up static identity map for 0x100000 - 0x10003c
[    0.312000] devtmpfs: initialized
[    0.343000] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns
[    0.359000] NET: Registered protocol family 16
[    0.375000] DMA: preallocated 256 KiB pool for atomic coherent allocations
[    0.765000] clocksource: Switched to clocksource timer
[    1.140000] NET: Registered protocol family 2
[    1.171000] tcp_listen_portaddr_hash hash table entries: 512 (order: 0, 4096 bytes)
[    1.171000] TCP established hash table entries: 1024 (order: 0, 4096 bytes)
[    1.187000] TCP bind hash table entries: 1024 (order: 0, 4096 bytes)
[    1.187000] TCP: Hash tables configured (established 1024 bind 1024)
[    1.187000] UDP hash table entries: 256 (order: 0, 4096 bytes)
[    1.203000] UDP-Lite hash table entries: 256 (order: 0, 4096 bytes)
[    1.203000] NET: Registered protocol family 1
[    1.218000] NetWinder Floating Point Emulator V0.97 (extended precision)
[    1.250000] workingset: timestamp_bits=30 max_order=13 bucket_order=0
[    1.281000] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 254)
[    1.281000] io scheduler mq-deadline registered
[    1.281000] io scheduler kyber registered
[    4.734000] Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled
[    4.906000] printk: console [ttyS0] disabled
[    4.906000] 40020000.serial: ttyS0 at MMIO 0x40020000 (irq = 17, base_baud = 230400) is a 8250
[    4.921000] printk: console [ttyS0] enabled
[    4.921000] printk: console [ttyS0] enabled
[    4.921000] printk: bootconsole [earlycon0] disabled
[    4.921000] printk: bootconsole [earlycon0] disabled
[    5.093000] brd: module loaded
[    5.796000] loop: module loaded
[    5.921000] null: module loaded
[    6.109000] phram: rootfs device: 0x2000000 at 0x10000000
[    6.140000] NET: Registered protocol family 10
[    6.203000] Segment Routing with IPv6
[    6.218000] sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver
[    6.296000] random: fast init done
[    6.453000] EXT2-fs (mtdblock0): warning: mounting unchecked fs, running e2fsck is recommended
[    6.484000] VFS: Mounted root (ext2 filesystem) on device 31:0.
[    6.484000] devtmpfs: mounted
[    6.640000] Freeing unused kernel memory: 1024K
[    6.656000] Run /linuxrc as init process
Starting syslogd: OK
Starting klogd: OK
Running sysctl: OK
Initializing random number generator: OK
Saving random seed: [   13.515000] random: dd: uninitialized urandom read (512 bytes read)
OK
Starting network: OK

Welcome to ARM Emulator
armemulator login: root

Todo:
 1.添加网络支持****
 2.优化代码性能*****
 3.添加声音支持**
 4.添加图形支持*


2020年3月11日星期三

arm_emulator: 用C写的一个兼容ARMv4指令集的模拟器

       大概2000多行C代码,可以移植。支持所有基本指令集,CP15协处理器,所有异常、支持MMU。没有浮点fpu和除法、非对齐访问以及16位指令thumb支持。支持单步运行调试。

MMU相关的CP15寄存器:
0:ID 编码&cache 类型(只读)
1:控制位
2:地址转换表基地址(TTB)
3:域访问控制位
5:失效状态寄存器(FSR)
6:失效地址寄存器(FAR)

外设寄存器:
中断控制器寄存器(0x4001f040)
(0x0)MSK:中断屏蔽寄存器(置1有效)
(0x4)PND:中断状态寄存器(硬件置位、软件清零)
定时器寄存器(0x4001f020)
(0x0)CNT: 计数值寄存器(只读,单位毫秒)
(0x4)EN:定时器使能寄存器
兼容8250 的串口寄存器(0x40020000)
(0x0)DLL, THR, RBR:传输保持&接收缓存寄存器
(0x4)DLH, IER:中断使能寄存器
(0x8)IIR, FCR:中断指示(读)&FIFO控制寄存器(写)
(0xC)LCR:线路控制寄存器
....
指令计数器(0x4001f030)
(0x0)CC:读取已执行的指令数,调试用(32bit)

中断:
0:10ms定时器
1:串口

移植了keil&gcc裸机、freeRTOS、linux 5.1 内核的工程,文件系统用的buildroot,基于initramfs,可以登录进串口终端。

CPU信息:
[root@armemulator ~]# cat /proc/cpuinfo
processor       : 0
model name      : ARM920T rev 5 (v4l)
BogoMIPS        : 20.24
Features        : swp half
CPU implementer : 0x41
CPU architecture: 4T
CPU variant     : 0x0
CPU part        : 0x920
CPU revision    : 5
Hardware        : ARM Emulator (Device Tree Support)
Revision        : 0000
Serial          : 0000000000000000

模拟器涉及的平台相关函数:
IO:
#define KBHIT()   kbhit() 
#define GETCH()   getch()
#define PUTCHAR(c)   putchar(c)
时钟:
#define GET_TICK()   (clock()*1000/CLOCKS_PER_SEC)

地址:
项目地址: https://github.com/hxdyxd/arm_emulator
Linux内核地址:https://github.com/hxdyxd/arm-emulator-linux

2019年1月29日星期二

这是一个测试

这是一个测试
这是一个测试
这是一个测试
这是一个测试