add plic.md and clint.md for k210
This commit is contained in:
parent
162286c030
commit
db89f65dda
|
@ -0,0 +1,104 @@
|
|||
#### 简介
|
||||
|
||||
管理核间中断。
|
||||
|
||||
#### 寄存器
|
||||
|
||||
| 地址 | 寄存器名 | 描述 |
|
||||
| ------------------------- | -------------- | ------------------------------------------------------------ |
|
||||
| 0x02000000~<br>0x02003FFF | msip[4095] | 4094个核的msip寄存器(机器级软件中断待处理寄存器),每个msip寄存器只有第一位(MSIP位)是有效的,用于记录是否发生了机器级软件中断 |
|
||||
| 0x02004000~<br>0x0200BFF0 | mtimecmp[4095] | 4094个核的mtimecmp寄存器。当mtime中的值大于等于某个核的mtimecmp中的值时,那个核上就会发生计时器中断。计时器中断会影响对应核mip寄存器的MTIP位。 |
|
||||
| 0x0200BFF8 | mtime | mtime寄存器。是一个64位寄存器,记录了记数器的实时值。 |
|
||||
|
||||
#### 操作
|
||||
|
||||
##### 初始化clint计时器
|
||||
|
||||
clint_timer_init
|
||||
|
||||
- clear_csr(mie, MIP_MTIP),禁止机器级计时器中断
|
||||
|
||||
##### 从clint计时器获取时间
|
||||
|
||||
clint_get_time
|
||||
|
||||
- 返回寄存器mtime的值
|
||||
|
||||
##### clint计时器的开启或关闭
|
||||
|
||||
clint_timer_start
|
||||
|
||||
- 设置计时器的时间间隔,以及是否单发射
|
||||
- 设置当前核的mtimecmp的值,即mtime的值加上一个cycles
|
||||
- 在mstatus寄存器里使能机器级中断
|
||||
- 在mie寄存器里使能计时器中断
|
||||
|
||||
clint_timer_stop
|
||||
|
||||
- clear_csr(mie, MIP_MTIP),禁止机器级计时器中断
|
||||
|
||||
##### 计时器间隔的获取与设置
|
||||
|
||||
clint_timer_get_interval
|
||||
|
||||
- 直接返回当前核下时间间隔的值
|
||||
|
||||
clint_timer_set_interval
|
||||
|
||||
- 直接设置当前核下时间间隔的值
|
||||
- 通过时间间隔计算出cycles的值
|
||||
|
||||
##### 计时器单发射的获取与设置
|
||||
|
||||
clint_timer_get_single_shot
|
||||
|
||||
- 直接获取当前核single_shot的值
|
||||
|
||||
clint_timer_set_single_shot
|
||||
|
||||
- 直接设置当前核single_shot的值
|
||||
|
||||
##### 计时器超时的时候用户回调函数的注册与取消注册
|
||||
|
||||
clint_timer_register
|
||||
|
||||
- 直接把函数指针赋值给结构体clint_timer_instance
|
||||
|
||||
clint_timer_unregister
|
||||
|
||||
- 直接把空指针赋值给clint_timer_register
|
||||
|
||||
##### 核间中间的初始化、使能、取消使能
|
||||
|
||||
clint_ipi_init
|
||||
|
||||
- 取消机器级软件中断
|
||||
|
||||
clint_ipi_enable
|
||||
|
||||
- 在mstatus寄存器里使能机器级中断
|
||||
- 在mie寄存器里使能机器级软中断
|
||||
|
||||
clint_ipi_disable
|
||||
|
||||
- 在mie寄存器里关闭机器级软中断
|
||||
|
||||
##### 核间中断的发送与清除
|
||||
|
||||
clint_ipi_send
|
||||
|
||||
- 将对应核的msip寄存器的MSIP位置1
|
||||
|
||||
clint_ipi_clear
|
||||
|
||||
- 将对应核的msip寄存器的MSIP位置0
|
||||
|
||||
##### 核间中断回调函数的注册与取消注册
|
||||
|
||||
clint_ipi_register
|
||||
|
||||
- 直接把函数指针赋值给结构体clint_ipi_instance
|
||||
|
||||
clint_ipi_unregister
|
||||
|
||||
- 直接把空指针赋值给clint_ipi_register
|
|
@ -0,0 +1,72 @@
|
|||
#### 中断源
|
||||
|
||||
| 编号 | 外设 | 描述 |
|
||||
| ----- | ------------------------------------------------------------ | -------- |
|
||||
| 0 | 无 | 无中断 |
|
||||
| 1~33 | SPI, I2S, I2C, UART, TIMER, RTC, WDT, APB, DVP, AI, FFT, DMA, UARTHS | 外设中断 |
|
||||
| 34~65 | GPIOHS0~31 | 外设中断 |
|
||||
|
||||
#### 中断寄存器在内存中的映射
|
||||
|
||||
| 地址 | 寄存器名 | 描述 |
|
||||
| -------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
|
||||
| 0x0c000000<br> ~0x0c000FFF | priority[1024] | 1023个优先级寄存器,对应所有外部中断源的优先级 |
|
||||
| 0x0c001000<br>~0x0c001FFF | u32[32] | pending array。一个bit对应一个中断源,所以只有前32个寄存器有效。 |
|
||||
| 0x0c002000<br>~0x0c1FFFFF | target[15872].enable[32] | 核x使能。每个核都需要32个寄存器来对应所有的中断。 |
|
||||
| 0x0c200000<br>~0x0FFFF004 | target[15872].priority_threshold<br>target[15872].claim_complete | 核x中断优先级的阈值,获取最高优先级的中断,完成中断的信号 |
|
||||
|
||||
#### 中断的操作
|
||||
|
||||
##### 初始化外部中断
|
||||
|
||||
plic_init
|
||||
|
||||
- target[core_id].enable[i]=0,当前核的使能位置0
|
||||
- priority[i]=0,所有中断源的优先级置0
|
||||
- target[core_id].priority_threshold=0,当前核的优先级阈值置0
|
||||
- 清空所有核上中断源的pending bit(代码比较怪,无法理解)
|
||||
- set_csr(mie, MIP_MEIP),使能机器级外中断
|
||||
|
||||
##### 中断开启与关闭
|
||||
|
||||
plic_irq_enable
|
||||
|
||||
- 将中断号对应的使能寄存器赋值给current
|
||||
- 将中断号对应的使能位写入current
|
||||
- 将current写回到中断号对应的使能寄存器
|
||||
|
||||
plic_irq_disable
|
||||
|
||||
- 将中断号对应的使能寄存器赋值给current
|
||||
- 清空current上中断号对应的使能位
|
||||
- 将current写回到中断号对应的使能寄存器
|
||||
|
||||
##### 中断优先级的获取与设置
|
||||
|
||||
plic_set_priority
|
||||
|
||||
- 直接给对应的优先级寄存器赋值
|
||||
|
||||
plic_get_priority
|
||||
|
||||
- 直接返回对应的优先级寄存器的值
|
||||
|
||||
##### 中断请求的认领与完成
|
||||
|
||||
plic_irq_claim
|
||||
|
||||
- 直接返回target[core_id].claim_complete的值
|
||||
|
||||
plic_irq_complete
|
||||
|
||||
- 直接给target[core_id].claim_complete赋值
|
||||
|
||||
##### 用户回调函数的注册与取消注册
|
||||
|
||||
plic_irq_register
|
||||
|
||||
- 把函数指针赋值给对应的结构体plic_instance
|
||||
|
||||
plic_irq_unregister
|
||||
|
||||
- 把空指针赋值为对应的结构体plic_instance
|
|
@ -346,7 +346,7 @@ ecall是用来触发异常的,而int是用来触发中断的,感觉它们用
|
|||
| x3 | gp | 全局指针 | 无 |
|
||||
| x4 | tp | 线程指针 | 无 |
|
||||
| x5 | t0 | 临时寄存器/备用连接寄存器 | 调用者 |
|
||||
| x6-7 | t1-2 | s临时寄存器 | 调用者 |
|
||||
| x6-7 | t1-2 | 临时寄存器 | 调用者 |
|
||||
| x8 | s0/fp | 保存寄存器/桢指针 | 被调用者 |
|
||||
| x9 | s1 | 保存寄存器 | 被调用者 |
|
||||
| x10-11 | a0-1 | 函数参数/返回值 | 调用者 |
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
#### 简介
|
||||
|
||||
Binder用于进程间通信。java层Binder架构是native层Binder架构的封装。
|
||||
|
||||
#### framework层
|
||||
|
||||
- frameworks/base/core/java/android/os/IBinder.java
|
||||
|
||||
接口IBinder
|
||||
|
||||
- frameworks/base/core/java/android/os/Binder.java
|
||||
|
||||
类Binder
|
||||
|
||||
类BinderProxy
|
||||
|
||||
- frameworks/base/core/java/com/android/internal/os/BinderInternal.java
|
||||
|
||||
类BinderInternal
|
||||
|
||||
##### Binder框架的初始化
|
||||
|
||||
frameworks/base/core/jni/android_util_Binder.cpp
|
||||
|
||||
register_android_os_Binder负责Binder框架的初始化。其实就是提前获取JNI层的一些使用信息,通过JNI建立起Java Binder和Native Binder互通的桥梁。
|
||||
|
||||
- int_register_android_os_Binder完成Binder类的初始化。
|
||||
|
||||
kBinderPathName为Binder类的路径名
|
||||
|
||||
gBinderOffsets结构体用以保存Binder类在JNI层保存的一些信息,包括类Binder的全局引用、成员函数execTransact的MethodID、成员mObject的FieldID
|
||||
|
||||
用RegisterMethodsOrDie注册Binder类中native函数的实现
|
||||
|
||||
- int_register_android_os_BinderInternal完成BinderInternal类的初始化。
|
||||
|
||||
与int_register_android_os_Binder类似
|
||||
|
||||
- int_register_android_os_BinderProxy完成BinderProxy类的初始化。
|
||||
|
||||
gErrorOffsets用来和Error类打交道
|
||||
|
||||
gBinderProxyOffsets用来和BinderProxy打交道
|
||||
|
||||
gClassOffsets用来和Class类打交道
|
||||
|
||||
用RegisterMethodsOrDie注册BinderProxy类中native函数的实现
|
||||
|
||||
##### Binder的工作原理
|
||||
|
||||
##### AIDL的原理
|
|
@ -0,0 +1,74 @@
|
|||
#### 简介
|
||||
|
||||
property即属性,由key和value组成,key和value均为字符串。它用来记录系统设置或进程之间的信息交换,是全局可见的。每个进程可以get或set属性。
|
||||
|
||||
- ro.* : 只读属性。一旦设置,不能修改。
|
||||
- persist.* : 此属性的值将同时写入/data/property。
|
||||
- net.* : net.change将会随此属性自动修改。
|
||||
- ctrl.start和ctrl.stop : 用来启动和停止服务,启动的结果会放在init.svc.<服务名>属性中。
|
||||
|
||||
##### 属性服务的创建
|
||||
|
||||
属性服务由init进程创建,其它进程通过属性服务来获取或设置属性。
|
||||
|
||||
`system/core/init/init.cpp`
|
||||
|
||||
- init进程分配一个共享的内存区域来存储属性
|
||||
|
||||
- property_init : 调用__system_property_area_init
|
||||
|
||||
- start_property_service : init进程启动属性服务
|
||||
|
||||
用`CreateSocket`函数创建socket资源并绑定
|
||||
|
||||
用listen函数来监听
|
||||
|
||||
`system/core/init/property_service.cpp`
|
||||
|
||||
- 属性服务调用`__system_property_init`来初始化属性系统的共享内存
|
||||
|
||||
- 启动属性服务时,从以下文件加载默认属性值
|
||||
|
||||
/default.prop
|
||||
|
||||
/system/build.prop
|
||||
|
||||
/system/default.prop
|
||||
|
||||
/data/local.prop
|
||||
|
||||
- 通过handle_property_set_fd来处理监听到的socket消息
|
||||
|
||||
accept4函数等待建立通信
|
||||
|
||||
getsockopt函数获取套接字相关信息
|
||||
|
||||
socket.RecvUint32函数接收属性设置请求命令
|
||||
|
||||
switch语句来处理接收到的命令,最终都是通过handle_property_set来干活的
|
||||
|
||||
##### 属性的操作
|
||||
|
||||
`frameworks/base/core/java/android/os/SystemProperties.java`
|
||||
|
||||
- 类SystemProperties的get方法用于获取属性值,set方法用于设置属性值。
|
||||
- 类SystemProperties通过JNI调用实现get和set方法。
|
||||
|
||||
`frameworks/base/core/jni/android_os_SystemProperties.cpp`
|
||||
|
||||
- JNI函数的具体实现是SystemProperties_set和SystemProperties_get。
|
||||
|
||||
`system/core/libcutils/properties.cpp`
|
||||
|
||||
- property_init
|
||||
|
||||
- property_get
|
||||
- property_set
|
||||
|
||||
`bionic/libc/include/sys/system_properties.h`
|
||||
|
||||
`bionic/libc/bionic/system_properties.cpp`
|
||||
|
||||
- `__system_property_set`:设置系统属性,将value赋值给key
|
||||
- `__system_property_get`:不赞成使用。应使用`__system_property_read_callback`
|
||||
- `__system_property_area_init`:将系统属性的内存区域初始化为只读模式
|
|
@ -90,7 +90,7 @@ init是第一个进程,也叫root进程或所有进程的父进程。在此阶
|
|||
|
||||
> SELinux是「Security-Enhanced Linux」的简称,是美国国家安全局和SCC开发的 Linux的一个扩张强制访问控制安全模块。 在这种访问控制体系的限制下,进程只能访问那些在他的任务中所需要文件。
|
||||
|
||||
现在是在内核域,所以在SELinux policy加载后,需要再次执行init转换到init域。函数selinux_android_restorecon("/init", 0)就是做这个工作的。
|
||||
现在是在内核态,所以在SELinux policy加载后,需要再次执行init转换到用户态。函数selinux_android_restorecon("/init", 0)就是做这个工作的。
|
||||
|
||||
5. 开始第二阶段前的准备
|
||||
|
||||
|
|
|
@ -92,4 +92,20 @@ lunch命令定义在build/envsetup.sh里,用来让用户选择编译设备与
|
|||
|
||||
### 编译出的结果
|
||||
|
||||
在`out`目录下
|
||||
在`out`目录下
|
||||
|
||||
### 编译错误记录
|
||||
|
||||
> DEPMOD 4.9.109-android-x86_64-01316-g45b3cc90-dirty
|
||||
>
|
||||
> /root/szx/kernel/Makefile:1350: recipe for target '_modinst_post' failed
|
||||
> make[1]: *** [_modinst_post] Error 255
|
||||
> make[1]: Leaving directory '/root/szx/out/target/product/openthos/obj/kernel'
|
||||
> Makefile:152: recipe for target 'sub-make' failed
|
||||
> make: *** [sub-make] Error 2
|
||||
> make: Leaving directory '/root/szx/kernel'
|
||||
> [ 99% 99776/99781] build out/target/product/openthos/install.img
|
||||
> ninja: build stopped: subcommand failed.
|
||||
> 02:44:29 ninja failed with: exit status 1
|
||||
|
||||
问题分析:我的情况是少了kmod,把它安装上即可。`sudo apt install kmod`。另,还应检查`syslinux genisoimage gettext bc dosfstools mtools kmod`是否都安装齐全。另:从这里是看不出来问题在哪的,要从往前翻,找到真正错误的地方。
|
|
@ -1,13 +0,0 @@
|
|||
> DEPMOD 4.9.109-android-x86_64-01316-g45b3cc90-dirty
|
||||
>
|
||||
> /root/szx/kernel/Makefile:1350: recipe for target '_modinst_post' failed
|
||||
> make[1]: *** [_modinst_post] Error 255
|
||||
> make[1]: Leaving directory '/root/szx/out/target/product/openthos/obj/kernel'
|
||||
> Makefile:152: recipe for target 'sub-make' failed
|
||||
> make: *** [sub-make] Error 2
|
||||
> make: Leaving directory '/root/szx/kernel'
|
||||
> [ 99% 99776/99781] build out/target/product/openthos/install.img
|
||||
> ninja: build stopped: subcommand failed.
|
||||
> 02:44:29 ninja failed with: exit status 1
|
||||
|
||||
问题分析:我的情况是少了kmod,把它安装上即可。`sudo apt install kmod`。另,还应检查`syslinux genisoimage gettext bc dosfstools mtools kmod`是否都安装齐全。另:从这里是看不出来问题在哪的,要从往前翻,找到真正错误的地方。
|
|
@ -1,38 +0,0 @@
|
|||
#### iso用于从cdrom中安装(BIOS)
|
||||
|
||||
```
|
||||
# 1. 创建虚拟磁盘
|
||||
qemu-img create a.raw +20G
|
||||
sudo parted a.raw
|
||||
mklabel msdos
|
||||
mkpart p ext4 1 20G
|
||||
quit
|
||||
|
||||
# 2. 安装
|
||||
qemu-system-x86_64 -hda a.raw -enable-kvm -m 4096 -cdrom you-download.iso -boot once=d
|
||||
|
||||
# 3. 启动
|
||||
qemu-system-x86_64 -hda a.raw -enable-kvm -m 4096 -vga cirrus
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### img用于从U盘安装(UEFI)
|
||||
|
||||
```
|
||||
# 1. 创建虚拟磁盘
|
||||
qemu-img create a.raw +20G
|
||||
sudo parted a.raw
|
||||
mklabel gpt
|
||||
mkpart p ext4 1 20G
|
||||
quit
|
||||
|
||||
# 2. 安装
|
||||
wget https://www.kraxel.org/repos/jenkins/edk2/edk2.git-ovmf-x64-0-20180807.281.gc526dcd40f.noarch.rpm
|
||||
# 提取usr/share/edk2.git/ovmf-x64/OVMF-pure-efi.fd
|
||||
qemu-system-x86_64 -bios OVMF-pure-efi.fd -hda a.raw -enable-kvm -m 4096 -hdb you-download.img -boot once=d
|
||||
|
||||
# 3. 启动
|
||||
qemu-system-x86_64 -hda a.raw -enable-kvm -m 4096 -vga cirrus
|
||||
```
|
||||
|
|
@ -18,4 +18,45 @@
|
|||
|
||||
第一行指定根目录所在的分区,第二行指定内核为kernel,后面跟着的都是参数,可以看到它指定了openthos的三个分区,第三行是指定内存中的文件系统,辅助内核启动。
|
||||
|
||||
2. 执行命令`sudo update-grub`,相当于`sudo grub-mkconfig -o /boot/grub/grub.cfg`,重新为grub生成配置文件。`grub-mkconfig`命令默认是将配置输出到标准输出的。
|
||||
2. 执行命令`sudo update-grub`,相当于`sudo grub-mkconfig -o /boot/grub/grub.cfg`,重新为grub生成配置文件。`grub-mkconfig`命令默认是将配置输出到标准输出的。
|
||||
|
||||
#### 虚拟机中安装Openthos
|
||||
|
||||
##### iso用于从cdrom中安装(BIOS)
|
||||
|
||||
```
|
||||
# 1. 创建虚拟磁盘
|
||||
qemu-img create a.raw +20G
|
||||
sudo parted a.raw
|
||||
mklabel msdos
|
||||
mkpart p ext4 1 20G
|
||||
quit
|
||||
|
||||
# 2. 安装
|
||||
qemu-system-x86_64 -hda a.raw -enable-kvm -m 4096 -cdrom you-download.iso -boot once=d
|
||||
|
||||
# 3. 启动
|
||||
qemu-system-x86_64 -hda a.raw -enable-kvm -m 4096 -vga cirrus
|
||||
```
|
||||
|
||||
|
||||
|
||||
##### img用于从U盘安装(UEFI)
|
||||
|
||||
```
|
||||
# 1. 创建虚拟磁盘
|
||||
qemu-img create a.raw +20G
|
||||
sudo parted a.raw
|
||||
mklabel gpt
|
||||
mkpart p ext4 1 20G
|
||||
quit
|
||||
|
||||
# 2. 安装
|
||||
wget https://www.kraxel.org/repos/jenkins/edk2/edk2.git-ovmf-x64-0-20180807.281.gc526dcd40f.noarch.rpm
|
||||
# 提取usr/share/edk2.git/ovmf-x64/OVMF-pure-efi.fd
|
||||
qemu-system-x86_64 -bios OVMF-pure-efi.fd -hda a.raw -enable-kvm -m 4096 -hdb you-download.img -boot once=d
|
||||
|
||||
# 3. 启动
|
||||
qemu-system-x86_64 -hda a.raw -enable-kvm -m 4096 -vga cirrus
|
||||
```
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#### pm
|
||||
|
||||
```
|
||||
|
||||
pm disable <package> # 使package不可用
|
||||
```
|
||||
|
||||
#### wm
|
||||
|
@ -19,3 +19,15 @@ wm overscan [reset|LEFT,TOP,RIGHT,BOTTOM] # 设置屏幕显示区域
|
|||
# 4个参数是距离左,上,右,下的距离
|
||||
```
|
||||
|
||||
#### getprop
|
||||
|
||||
```
|
||||
getprop [NAME [DEFAULT]] # 查看系统属性
|
||||
```
|
||||
|
||||
#### setprop
|
||||
|
||||
```
|
||||
setprop NAME VALUE # 设置系统属性
|
||||
```
|
||||
|
||||
|
|
Loading…
Reference in New Issue