Skip to content

Commit a75afba

Browse files
committed
add linux-driver-reserved-memory
1 parent 3e29ea2 commit a75afba

File tree

5 files changed

+129
-18
lines changed

5 files changed

+129
-18
lines changed

content/2023 游戏总结.md

+19-15
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,19 @@ tags = ["游戏"]
1414

1515
## 双人游戏
1616

17-
自从和对象一起玩饥荒之后,先后尝试了很多双人游戏,通关一款就去 steam 上找新的游戏,乐此不疲
17+
众所周知,玩游戏最奢侈的配置就是朋友了。有朋友一起玩时,游戏的乐趣总是翻倍的
1818

1919
### [饥荒联机版](https://store.steampowered.com/app/322330)
2020

2121
!["dont-starve-together"](/assets/game_dont-starve-together.png)
2222

23-
这是我拉着对象入坑的第一款游戏,从前年开始玩的。一开始她看到高脚鸟在给我磕头,也想试玩一下,结果一发不可收拾,不知花了多少个夜晚在永恒领域里探索神秘的未知。
23+
**伟大,无需多言。**
2424

25-
一个人的饥荒玩到后期最深刻的体会其实是孤独,两个人的饥荒就只剩下此起彼伏的“救我”了。
25+
我在 steam 上买的第一款游戏就是饥荒,我和对象一起玩的第一款游戏也是饥荒。
26+
27+
饥荒占了我去年游戏时间的三分之一,已经算少了,前几年刚开始一起玩时经常玩到半夜两三点,打怪种地乐此不疲。而且 KLEI 还一直在推出新内容,让玩家总能找到新鲜感。
28+
29+
其实饥荒玩到后期最深刻的游戏体验是孤独,当偌大的永恒领域里所有的神秘未知都被探索完了,剩下一个不愁吃穿身披铥甲的玩家,只有几个傻不拉几的猪人在旁边转悠,一股孤独感就莫名袭来。KLEI 推出联机版可能就是出于这个考虑,但可能大多数人还是在玩单人联机。
2630

2731
### [星露谷物语](https://store.steampowered.com/app/413150/Stardew_Valley/)
2832

@@ -44,18 +48,6 @@ tags = ["游戏"]
4448

4549
大名鼎鼎的分手厨房(~~1 和 2 都通关了居然还没分手~~),从手忙脚乱到 sorry 全场,谁是 sorry 全场的那个人我就不说了。
4650

47-
### [城堡破坏者](https://store.steampowered.com/app/204360/Castle_Crashers/)
48-
49-
![castle-crasher](/assets/game_castle-crashers.png)
50-
51-
很好玩!横版闯关,打boss救公主,有小时候玩热血格斗那味儿了!角色的技能种类足够丰富,就是每个角色都要单独升级,想要体验全角色要花很多时间。
52-
53-
### [猫咪斗恶龙 II](https://store.steampowered.com/app/914710/Cat_Quest_II/)
54-
55-
![cat-quest2](/assets/game_cat-quest.png)
56-
57-
平面版的冒险闯关游戏,体量比较小,值得一玩。
58-
5951
### [双人成行](https://store.steampowered.com/app/1426210/)
6052

6153
![it-takes-two](/assets/game_it-takes-two.png)
@@ -82,6 +74,18 @@ tags = ["游戏"]
8274

8375
美术、音乐与剧情都是一流的,堪称精美的艺术品。游戏里你将扮演一个灵魂摆渡人(双人的话是一个控制人,一个控制猫),驾驶着一艘船在生死边缘航行,帮助即将离世的灵魂完成最后的心愿,送他们前往来生。玩游戏的时候经常舍不得把船上的人送走,但为了推进剧情又不得不这么做,还好最后在永恒之门的一个拥抱总能让人释怀。唯一的缺点是后期任务有些乏味,硬是把流程拖得太长了。
8476

77+
### [城堡破坏者](https://store.steampowered.com/app/204360/Castle_Crashers/)
78+
79+
![castle-crasher](/assets/game_castle-crashers.png)
80+
81+
很好玩!横版闯关,打boss救公主,有小时候玩热血格斗那味儿了!角色的技能种类足够丰富,就是每个角色都要单独升级,想要体验全角色要花很多时间。
82+
83+
### [猫咪斗恶龙 II](https://store.steampowered.com/app/914710/Cat_Quest_II/)
84+
85+
![cat-quest2](/assets/game_cat-quest.png)
86+
87+
平面版的冒险闯关游戏,体量比较小,值得一玩。
88+
8589
### [九张羊皮纸](https://store.steampowered.com/app/471550/)
8690

8791
![Nine Parchments](/assets/game_nine-parchments.png)

content/C++ 类型萃取的实现.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title = "C++ 类型萃取的实现"
33
date = 2020-04-01T22:18:04+08:00
44
slug = "cpp-traits"
55
[taxonomies]
6-
tags = ["cpp", "traits"]
6+
tags = ["cpp"]
77
+++
88

99
以前看《Effective C++》时,很多条款都没有仔细看,对类型萃取有点印象,但又说不出个所以然来。

content/about/_index.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
+++
2+
title = "关于我"
3+
+++
4+
5+
> 祝愿自己永远喜欢玩游戏

content/linux 驱动预留内存.md

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
+++
2+
title = "linux 驱动预留内存"
3+
date = 2023-04-01T21:20:15+08:00
4+
slug = "linux-driver-reserved-memory"
5+
[taxonomies]
6+
tags = ["linux 驱动"]
7+
+++
8+
9+
嵌入式项目中可能会碰到这样的需求,需要在内存中预留出一块比较大的空间在驱动里使用,并且这块空间的物理地址必须是固定的。而内核里常用的 `kmalloc()` 分配出的内存物理地址是不固定的,我们需要在内核启动之前预留一块空间出来。
10+
11+
## 方法一:指定内存大小
12+
13+
默认情况下 linux 会使用整块内存,如果你的内存是 1G,那么内核会将这 1G 都收入囊中,你想使用只能向它申请。除非你在 uboot 里指定启动参数,规定内存大小:
14+
15+
```
16+
setenv bootargs console=ttyAMA0,115200 root=/dev/mmcblk0p1 rw mem=512M
17+
```
18+
19+
最后的 `mem=512M` 会让 linux 认为系统的内存本身就只有 512M,那么剩下的 512M 物理内存你就可以随意使用了。
20+
21+
## 方法二:预留内存
22+
23+
预留内存比直接指定内存大小更加符合驱动开发的规则,但用起来稍微复杂一些。
24+
25+
### 设备树配置
26+
27+
首先我们需要在设备树中通过 `reserved-memory` 节点预留出物理内存。下面的设备树文件是一个示例:
28+
29+
- 预留了 `0x10000000` 开始的大小为 `0x01000000` 的物理内存
30+
- 标签为 `somedev_reserved`,供设备节点引用
31+
- `no-map` 表示内核不会对该段内存作地址映射,`/proc/iomem` 中的 System RAM 也不会包括该内存区域
32+
33+
```
34+
\{
35+
reserved-memory {
36+
#address-cells = <1>;
37+
#size-cells = <1>;
38+
ranges;
39+
somedev_reserved: buffer@0x1f000000 {
40+
no-map;
41+
reg = <0x10000000 0x01000000>;
42+
};
43+
};
44+
};
45+
```
46+
47+
然后在用到需要用到预留内存的驱动设备节点中,使用 `memory-region` 分配预留的内存区域:
48+
49+
```
50+
\{
51+
somedev@0 {
52+
compatible = "xlnx,dev1";
53+
memory-region = <&somedev_reserved>;
54+
}
55+
}
56+
```
57+
58+
### 驱动程序
59+
60+
驱动程序里要使用这块内存,需要先解析自己的设备树节点拿到物理地址,再选择合适的映射方式拿到虚拟地址。其中映射又分为带缓存和不带缓存两种方式。
61+
62+
#### 带缓存映射
63+
64+
将预留内存用 `memremap` 映射,带有缓存,可以直接读写:
65+
66+
```c
67+
// 获得预留内存的设备树节点(memory-region 指向 somedev_reserved)
68+
struct device_node *np = of_parse_phandle(dev->of_node, "memory-region", 0);
69+
if (!np) {
70+
dev_err(dev, "No memory-region specified\n");
71+
return -1;
72+
}
73+
74+
// 获得内存资源地址(存在 struct resource 中)
75+
struct resource r;
76+
int rc = of_address_to_resource(np, 0, &r);
77+
if (rc) {
78+
dev_err(dev, "No memory address assigned\n");
79+
}
80+
81+
// 物理地址
82+
unsigned long paddr = r.start;
83+
// 映射为虚拟地址
84+
unsigned long vaddr = (unsigned long)memremap(r.start, resource_size(&r), MEMREMAP_WB);
85+
86+
// 对虚拟地址直接读写
87+
*((u32 *)vadd) = 0x12345678; // 32位写
88+
pr_info("0x%08X\n", *((u32 *)vaddr)); // 32位读
89+
```
90+
91+
#### 不带缓存映射
92+
93+
如果不希望带缓存,使用 `ioremap`,需要调用 IO 函数读写:
94+
95+
```c
96+
// 映射为虚拟地址
97+
unsigned long vaddr = (unsigned long)ioremap(r.start, resource_size(&r));
98+
// IO 函数读写大块内存
99+
memcpy_toio();
100+
memcpy_fromio();
101+
memset_io();
102+
```

themes/cattery/theme.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ homepage = "https://github.com/zenlian/cattery"
55
# The minimum version of Zola required
66
min_version = "0.15.0"
77
# An optional live demo URL
8-
demo = "https://zenlian.github.io/cattery"
8+
demo = "https://zenlian.github.io"
99

1010
# The theme author info: you!
1111
[author]
@@ -31,7 +31,7 @@ colormode = "normal" # or "colorful"
3131
page_404_content = ["Oops!", "You're stuck in limbo."]
3232

3333
# icon ref to iconify-icon
34-
# internal 'path'/external 'link'
34+
# internal 'path'/external 'link'
3535
navigation = [
3636
{ icon = "mdi:tags", label = "tags", path = "tags"},
3737
{ icon = "mdi:user", label = "about", path = "about"}

0 commit comments

Comments
 (0)