[转帖]自动化运维:一键自动化脚本-shell
https://www.cnblogs.com/luoahong/articles/8456203.html
shell函数
1、分别在服务器和客户端上创建www用户
|
1
2
|
useradd wwwid wwww |
- 所有的web服务,都应该使用普通用户,所有的web服务都不应该监听80端口,除非负载均衡。8080
- 普通用户能启动80端口吗?通过和科技,比如给命令设置suid
- 生产指定uid
2、保证www用户登录其他的节点都不要输入密码
服务器端:
|
1
2
3
4
5
6
7
8
9
10
|
[root@node1 ~]# useradd www[root@node1 ~]# id www[root@node1 ~]# passwd www[root@node1 ~]# su www[root@node1 ~]# cd /home/www/[www@node1 ~]$ ssh-copy-id -i .ssh/id_rsa.pub www@172.16.14.116[www@node1 ~]$ ssh 172.16.14.116Last failed login: Sat Jan 13 09:56:41 CST 2018 from 172.16.14.115 on ssh:nottyThere were 3 failed login attempts since the last successful login.Last login: Sat Jan 13 09:23:02 2018 |
客户端:
|
1
2
3
4
5
6
7
8
9
10
|
[root@node2 ~]# useradd www[root@node2 ~]# id www[root@node2 ~]# passwd www[root@node2 ~]# su www[root@node2 ~]# cd /home/www/[www@node2 ~]$ ssh-copy-id -i .ssh/id_rsa.pub www@172.16.14.115[www@node2 ~]$ ssh 172.16.14.115Last failed login: Sat Jan 13 09:56:41 CST 2018 from 172.16.14.115 on ssh:nottyThere were 3 failed login attempts since the last successful login.Last login: Sat Jan 13 09:23:02 2018 |
3、写一个复杂的脚本
先把框架写出来,使用echo来测试框架的流程是否正确
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
#!/bin/bash # Shell Env SHELL_NAME="deploy.sh" SHELL_DIR="/home/www" SHELL_LOG="{SHELL_DIR}/${SHELL_NAME}.log" # Code Env CODE_DIR="/deploy/code/deploy/" TMP_DIR="/deploy/config" TAR_DIR="/deploy/tar" LOCK_FILE="/tmp/deploy.lock" usage(){ echo $"Usage: $0[ deploy|rollback]" } shell_lock(){ touch ${LOCK_FILE} } shell_unlock(){ rm -f ${LOCK_FILE} } code_get(){ echo code_get; sleep 2; } code_build(){ echo code_build; sleep 2; } code_config(){ echo code_config; sleep 2; } code_tar(){ echo code_tar; sleep 2; } code_scp(){ echo code_scp; sleep 1; } cluster_node_remove(){ echo cluster_node_remove; sleep 1; } code_deploy(){ echo code_deploy; } config_diff(){ echo config__diff; } code_test(){ echo code_test; } cluster_node_in(){ echo cluster_node_in; } main(){ if [ -f $LOCK_FILE ];then echo "Deploy is running"&& exit; fi DEPLOY_METHOD=$1 case $DEPLOY_METHOD in deploy) shell_lock; code_get; code_build; code_config; code_tar; code_scp; cluster_node_remove; code_deploy; config_diff; code_test; cluster_node_in; shell_unlock; ;; rollback) shell_lock; rollback; shell_unlock; ;; *) usage; esac } |
4、什么也没提示?在末尾添加 man $1
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
main(){ DEPLOY_METHOD=$1 case $DEPLOY_METHOD in deploy) shell_lock; ;; rollback) shell_lock; ;; *) usage; esac}main $1 |
本节小结:
1、凡是不记录日志的脚本就是耍流氓

2、这个脚本能不能多个人同时执行?
1、最好不要,但是运维团队有很多人,我如何知道别人有没有执行?
答:我写一个锁文件

1、锁文件放那?
答:放在/tmp/deploy.lock" 因为放在下www没有权限
2、系统的锁文件放哪里?
|
1
|
/var/run/lock |
3、看不出来?
答:sleep60秒

4、不是脚本的$1匙函数的$1

5、在两台电脑上都要用到所以定义为变量

2、功能实现
1、日志函数
|
1
2
3
4
5
6
7
8
9
10
11
|
#Date/Time VeriablesLOG_DATE='date "+%Y-%m-%d"'LOG_TIME='date "+%H-%M-%S"'CDATE=$(date "+%Y-%m-%d")CTIME=$(date "+%H-%M-%S")....writelog(){ LOGINFO=$1 echo "${CDATE} ${CTIME}: ${SHELL_NAME}: ${LOGINFO}" >> ${SHELL_LOG}} |
1、希望在很多地方记录日志
echo一行,写到一个文件里,记日志还要记时间
方法1:写一个日志的函数,每次调用这个函数
方法2:在每一个函数里写一个echo,然后写在那个位置,还要记时间
2、日志函数的好处?
- 这个函数可以复制,以后写别的脚本直接改改就可以
- 每一个函数里都写一个函数
3、shell是如何解析的?
从上倒下逐行执行
4、遇到函数怎么办?
先加载不执行
5、日志的内容从哪来?
从参数来:$1
6、脚本名称:
当前日期+脚本名称+日志内容
难保你以后会写在一起所以要区分开
7、时间是不是不能变?
我就不需要它变:
1、打包的时候不能变,包里有有日期和时间包名不能变
2、打包如何命名?
是scp时间不对,包就找不着了
|
1
2
|
LOG_DATE='date "+%Y-%m-%d"'LOG_TIME='date "+%H-%M-%S"' |
- 一个是让执行 记日志用的
- 一个不让执行 做别的用处
- 已经执行了,在后面就不变了
2、get代码函数
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#Code EnvPRO_NAME="web-demo"CODE_DIR="/deploy/code/web-demo"CONFIG_DIR="/deploy/config/web-demo"TMP_DIR="/deploy/tmp"LOCK_FILE="/tmp/deploy.lock".......code_get(){ writelog "code_get"; cd $CODE_DIR && echo "git pull" cp -r ${CODE_DIR} ${TMP_DIR}/ API_VERL=$(git show |grep commit | cut -d ' ' -f2) API_VER=$(echo ${API_VERL:0:6}) |
1、代码应该放在那?
放在CODE_DIR="/deploy/code/web-demo"目录下
2、配置文件能直接放CODE_DIR这吗?
不能,专门用于git更新的目录
如果你把文件拷贝到这里,所有的包里面都有这个文件
一不小心多放了一个,那个可不会pull
3、怎样区分是仓库的还是我copy过来的?
也能区分 看git状态,本地状态 正常区分不了
更新完之后copy走,放着也行出故障了你就知道是什么意思了!
4、复制到哪?
TMP_DIR
5、为什么对web-demo要重命名?
- 复制过去要重命名
- 打包的时候还要重命名
- 每次都覆盖那就乱了
6、要怎样重命名?
时间+版本号?
1、svn怎样获取版本号?
2、git如何获取版本号?
API_VERL=$(git show |grep commit | cut -d ' ' -f2)
3、配置文件函数
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#Code EnvPRO_NAME="web-demo"CODE_DIR="/deploy/code/web-demo"CONFIG_DIR="/deploy/config/web-demo"TMP_DIR="/deploy/tmp"LOCK_FILE="/tmp/deploy.lock"......code_config(){ writelog "code_config" /bin/cp -r ${CONFIG_DIR}/base/* ${TMP_DIR}/"${PRO_NAME}" PKG_NAME="${PKG_NAME}"_"$API_VER"_"${CDATE}-${CTIME}" cd ${TMP_DIR} && mv ${PKG_NAME} ${PKG_NAME}}} |
1、我是哪个项目的配置文件?
|
1
|
CONFIG_DIR="/deploy/config/web-demo" |
2、为什么加/bin/cp -r?
|
1
|
/bin/cp -r ${CONFIG_DIR}/base/* ${TMP_DIR}/"${PRO_NAME}" |
1、有可能我文件下还有目录呢!
2、我拷贝的那个目录下有那个配置文件
有一测试有权限,犯二提交了一个相同的配置文件 你没有覆盖连到测试库了
大家打开的都是测试的库
开发可以错,测试可以错,运维不可以错 为什么你上线的时候也没发现?
每一个小细节都是有意义不是瞎写
3、复制和打包可以放在一个里面,为什么把包名做成一个变量?
- 很多地方都用到
- 包名很长
- 包名本身也包含变量
4、为什么要全写成变量
因为不只为这一个脚本,写别的脚本改改就可以啦!
5、为什么tmp需要定期进行清理?
部署几个月可以,时间久磁盘就满了
有时间了就好删除了,解决了各种方式
只有版本号你怎样删?把15年的全删了
4、打包函数
|
1
2
3
4
5
|
code_tar(){ writelog "code_tar" cd ${TMP_DIR} && tar czf ${PKG_NAME}.tar.gz ${PKG_NAME} writelog "${PKG_NAME}.tar.gz"} |
1、为什么要写&&?
函数和函数之间可不知道上一级目录是什么!!!
不单独搞一行,如果目录不存在进去了可能不是你想要的
5、scp到目标服务器
|
1
2
3
4
5
6
7
|
code_scp(){ writelog "code_scp" for node in $PRE_LIST;do for node in $GROUP1_LIST;do scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot/ done} |
1、统一用一个包的好处?
完全可以写一个for循环
我要加机器 在列表里加一行
减机器 在列表里减去一行
标准化的好处
2、为什么不能直接写在/opt?
- 没有权限
- 在opt创建一个/opt/webroot/复制到这
6、部署函数
|
1
2
3
4
5
6
7
8
|
group1_deploy(){ writelog "remove from cluster" for node in $GROUP1_LIST;do ssh $node "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz" ssh $node "rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo" done scp ${CONFIG_DIR}/other/192.168.56.12.crontab.xml 192.168.56.12:/webroot/web-demo/crontab.xml} |
1、项目之间应该保持独立才对
2、你的目录放在那?
所有生产的web服务器的家目录都写在/webroot的项目名称下
3、为什么先创建软链接然后在复制差异文件?
路径写的少,要不然你写到解压后的路径下
如果没有生成我就不复制
生产部署的时候,没部署成功结果scp复制过去了
4、第一次手动创建一个因为 没有会报错。
|
1
2
3
4
|
su -wwwcd /webroot/touch web-demo用salt就要先touch文件 |
5、&&不能去掉,因为以后部署时候我要先删除才能软链接
6、一个软连接连一毫秒都花不了
3、脚本扩展
1、每个节点上各装一个apache
|
1
|
yum install httpd -y |
2、修改配置文件以下两处
|
1
|
vim /etc/httpd/conf/httpd.conf |

1、测试函数
|
1
2
3
4
5
6
7
8
|
url_test(){ URL=$1 curl -s --head $URL |grep '200 ok' if [ $? -ne 0 ];then shell_unlock; echo "test error" && exit; fi} |
1、测试一能访问就加入集群不能访问就移除集群
2、部署一个测一个通了才能加到集群里
生产是一个组一个组测试
并行和串行相结合
每一个组一个预生产节点
直接部署第二个节点
2、主函数
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
main(){ if [ -f $LOCK_FILE ]; then echo "Deploy is running" && exit; fi DEPLOY_METHOD=$1 ROLLBACK_VER=$2 case $DEPLOY_METHOD in deploy) shell_lock; code_get; code_build; code_config; code_tar; code_scp; pre_deploy; pre_test; group1_deploy; group1_test; shell_unlock; ;; rollback) shell_lock; rollback $ROLLBACK_VER; shell_unlock; ;; *) usage; esac}main $1 $2 |
1、先判断是否有文件,存在说明有人在执行直接退出
2、你是要部署还是要回滚,要是是部署先锁住脚本
从git上获取文件
进行编译
复制配置文件进去
打包并重命名
scp到所有机器(不分组)
晚上要做一个不算停机维护,所有机器都需要同时重启
涉及到数据一致性
组一部署集群
测试组一集群
4、秒级回滚

在某个地方记住上一个版本是啥,部署把版本写在一个文件里(紧急回滚的一个函数),然后读这个文件
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
rollback(){if [ -z $1 ];then shell_unlock; echo "please input rollback version" && exit;fi case $1 in list) ls -l /opt/webroot/*.tar.gz ;; *) rollback_fun $1 esac} |
部署还是回滚$1,回滚到那个版本是$2
传list的我就列出来,不传我就回滚
我可以只部署预生产,我部署机肯定有我其他的节点没有
|
1
2
3
4
|
rollback_fun(){ for node in $ROLLBACK_LIST;do ssh $node "rm -f /webroot/web-demo && ln -s /opt/webroot/$1 /webroot/web-demo" done |
1、如果list存在我就执行,不存在就结束for循环
2、远程ssh执行命令,引起来才能当成一个,因为中间还有空格

3、脚本的$2传到回滚函数里就是$1

5、gitlab部署和回滚
安装gitlab私有仓库,地址见运维社区gitlab
1、登陆修改root密码
2、备份:每天备份每小时也行
越频繁越好
分布式每个人的本地都有
6、完整脚本构造
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
#!/bin/bash#Dir Listmkdir -p /deploy/code/web-demomkdir -p /deploy/config/web-demo/basemkdir -p /deploy/config/web-demo/othermkdir -p /deploy/tarmkdir -p /deploy/tmpmkdir -p /opt/webrootmkdir /webrootchown -R www.www /deploychown -R www.www /opt/webrootchown -R www.www /webroot#Node ListPRE_LIST="192.168.56.11"GROUP1_LIST="192.168.56.12"ROLLBACK_LIST="192.168.56.11 192.168.56.12"#Date/Time VeriablesLOG_DATE='date "+%Y-%m-%d"'LOG_TIME='date "+%H-%M-%S"'CDATE=$(date "+%Y-%m-%d")CTIME=$(date "+%H-%M-%S")#Shell EnvSHELL_NAME="deploy_all.sh"SHELL_DIR="/home/www/"SHELL_LOG="${SHELL_DIR}/${SHELL_NAME}.log"#Code EnvPRO_NAME="web-demo"CODE_DIR="/deploy/code/web-demo"CONFIG_DIR="/deploy/config/web-demo"TMP_DIR="/deploy/tmp"LOCK_FILE="/tmp/deploy.lock"usage(){ echo $"Usage: $0{deploy|rollback[ list|version ]}"}writelog(){ LOGINFO=$1 echo "${CDATE} ${CTIME}: ${SHELL_NAME}: ${LOGINFO}" >> ${SHELL_LOG}}shell_lock(){ touch ${LOCK_FILE}}url_test(){ URL=$1 curl -s --head $URL |grep '200 ok' if [ $? -ne 0 ];then shell_unlock; echo "test error" && exit; fi}shell_unlock(){ rm -f ${LOCK_FILE}}code_get(){ writelog "code_get"; cd $CODE_DIR && echo "git pull" cp -r ${CODE_DIR} ${TMP_DIR}/ API_VERL=$(git show |grep commit | cut -d ' ' -f2) API_VER=$(echo ${API_VERL:0:6})}code_build(){ echo code_Build}code_config(){ writelog "code_config" /bin/cp -r ${CONFIG_DIR}/base/* ${TMP_DIR}/"${PRO_NAME}" PKG_NAME="${PKG_NAME}"_"$API_VER"_"${CDATE}-${CTIME}" cd ${TMP_DIR} && mv ${PKG_NAME} ${PKG_NAME}}}code_tar(){ writelog "code_tar" cd ${TMP_DIR} && tar czf ${PKG_NAME}.tar.gz ${PKG_NAME} writelog "${PKG_NAME}.tar.gz"}code_scp(){ writelog "code_scp" for node in $PRE_LIST;do for node in $GROUP1_LIST;do scp ${TMP_DIR}/${PKG_NAME}.tar.gz $node:/opt/webroot/ done}pre_deploy(){ writelog "remove from cluster" ssh $PRE_LIST "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz" ssh $PRE_LIST "rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo"}pre_test(){ url_test "http://${PRE_LIST}/index.html" echo "add to cluster"}group1_deploy(){ writelog "remove from cluster" for node in $GROUP1_LIST;do ssh $node "cd /opt/webroot && tar zxf ${PKG_NAME}.tar.gz" ssh $node "rm -f /webroot/web-demo && ln -s /opt/webroot/${PKG_NAME} /webroot/web-demo" done scp ${CONFIG_DIR}/other/192.168.56.12.crontab.xml 192.168.56.12:/webroot/web-demo/crontab.xml}group1_test(){ url_test "http://192.168.56.12/index.html" echo "add to cluster"}rollback_fun(){ for node in $ROLLBACK_LIST;do ssh $node "rm -f /webroot/web-demo && ln -s /opt/webroot/$1 /webroot/web-demo" done}rollback(){if [ -z $1 ];then shell_unlock; echo "please input rollback version" && exit;fi case $1 in list) ls -l /opt/webroot/*.tar.gz ;; *) rollback_fun $1 esac}main(){ if [ -f $LOCK_FILE ]; then echo "Deploy is running" && exit; fi DEPLOY_METHOD=$1 ROLLBACK_VER=$2 case $DEPLOY_METHOD in deploy) shell_lock; code_get; code_build; code_config; code_tar; code_scp; pre_deploy; pre_test; group1_deploy; group1_test; shell_unlock; ;; rollback) shell_lock; rollback $ROLLBACK_VER; shell_unlock; ;; *) usage; esac}main $1 $2 |
转载地址:https://github.com/unixhot/deploy-shell
[转帖]自动化运维:一键自动化脚本-shell的更多相关文章
- Linux centosVMware 自动化运维认识自动化运维、启动salt相关服务、saltstack配置认证、salt-key命令用法、saltstack远程执行命令、saltstack - grains、saltstack – pillar
一.认识自动化运维 传统运维效率低,大多工作人为完成 传统运维工作繁琐,容易出错 传统运维每日重复做相同的事情 传统运维没有标准化流程 传统运维的脚本繁多,不能方便管理 自动化运维就是要解决上面所有问 ...
- 自动化运维——一键安装MySQL
根据项目需要,前段时间在搞EMM系统各种安装包的自动化部署工作,主要包括一键安装和一键启动\停止功能.总结记录下来,以供后用. 本文主要是自动安装MySQL5.7.11版,Linux版脚本在CentO ...
- 自动化运维——MySQL备份脚本(二)
使用if语句编写MySQL备份脚本 代码: #!/bin/bash #auro backup mysql db #by steve yu #define backup path BAK_DIR=/da ...
- CheungSSH国产自动化运维工具开源Web界面
CheungSSH web2.0 发布文档 CheungSSH 简介 CheungSSH是一款国人自主研发的Linux运维自动化管理服务器软件,秉着为企业降低运营成本,解放管理员双手和自动化生产的理念 ...
- 使用Ansible实现数据中心自动化运维管理
长久以来,IT 运维在企业内部一直是个耗人耗力的事情.随着虚拟化的大量应用.私有云.容器的不断普及,数据中心内部的压力愈发增加.传统的自动化工具,往往是面向于数据中心特定的一类对象,例如操作系统.虚拟 ...
- 技术沙龙|京东云DevOps自动化运维技术实践
自动化测试体系不完善.缺少自助式的持续交付平台.系统间耦合度高服务拆分难度大.成熟的DevOps工程师稀缺,缺少敏捷文化--这些都是DevOps 在落地过程中,或多或少会碰到的问题,DevOps发展任 ...
- 自动化运维工具-Ansible之7-roles
自动化运维工具-Ansible之7-roles 目录 自动化运维工具-Ansible之7-roles Ansible Roles基本概述 Ansible Roles目录结构 Ansible Roles ...
- 自动化运维工具-Ansible之5-流程控制
自动化运维工具-Ansible之5-流程控制 目录 自动化运维工具-Ansible之5-流程控制 playbook条件语句 单条件 多条件 多条件运算 示例 playbook循环语句 with_ite ...
- 自动化运维工具-Ansible之2-ad-hoc
自动化运维工具-Ansible之2-ad-hoc 目录 自动化运维工具-Ansible之2-ad-hoc Ansible ad-hoc Ansible命令模块 Ansible软件管理模块 Ansibl ...
- 真正云原生的智能运维体系,阿里云发布ECS自动化运维套件
云计算的发展,推动了自动化运维.DevOps.AIOps 等趋势的兴起,在业务快速变化的今天,企业希望通过一套自动化运维的专家系统提高运维效率,为业务提供支撑. 传统的方式下,打造一套成熟的 DevO ...
随机推荐
- 教你几个部署多个nginx-ingress的注意事项
本文分享自华为云社区<nginx-ingress工作原理以及多nginx-ingress部署注意事项>,作者: 可以交个朋友. 一.nginx-ingress工作原理 nginx-ingr ...
- Python图像处理丨如何调用OpenCV绘制直方图
摘要:本篇文章主要讲解灰度直方图的基本概念,Python调用OpenCV实现绘制图像直方图. 本文分享自华为云社区<[Python图像处理] 十一.灰度直方图概念及OpenCV绘制直方图> ...
- 带你了解NB-IoT标准演进
摘要:本文将带大家详细了解NB-IoT标准演进与产业发展. 本文分享自华为云社区<一文带你了解NB-IoT标准演进与产业发展>,作者:万万万. 我们都知道,物联网的场景和手机.电脑在使用的 ...
- 用火山引擎DataTester,这家企业开始了“数据驱动增长”
年末购物季已至,近些年来,预售抵扣.平台满减.品类专享券.大额补贴--动辄四五种计算方法叠加的大促活动,让不少消费者"懵"感十足.同一样商品,到底谁家卖的最便宜?比价平台应声发展而 ...
- Linux 堡垒机命令行中如何上传下载文件(SecureCRT - SFTP)
通过堡垒机进入的 Linux 操作系统,无法直接使用 WinSCP 等工具进行文件的上传下载. 可使用 SecureCRT 先进入命令行模式 配置 配置 Linux 堡垒机的连接方式 连接 选择要进入 ...
- UltraEdit 去除文本中的空行,按指定字符换行
在将JSON格式的数据,整理到 Excel中查看时,可以通过文本替换的方式将JSON存到csv 后,使用 UltraEdit 编辑工具按需进行替换处理 去除多个空行 ^p^p 替换成 ^p 按逗号换 ...
- Djagno 使用locals()
Django使用locals()函数 locals()函数会以字典类型返回当前位置的全部局部变量 在 views.py中添加 #展示 class Goods_list(View): def get(s ...
- MVVM架构
一.MVVM架构和Jetpack MVVM即Model-View-ViewModel的缩写,它的出现是为了将图形界面和业务逻辑,数据模型进行解耦.在前面章节所学习的Jetpack组件,大部分是为了能够 ...
- 最全!即学即会 Serverless Devs 基础入门(下)
作者 | 刘宇(阿里云 Serverless 产品经理) 在上篇<最全!即学即会 Serverless Devs 基础入门>中,我们阐述了工具链的重要性,并对安装方式 & 密钥配置 ...
- S3C2440移植uboot之启动过程概述
上节烧写了uboot到开发板,不能运行.这节我们分析uboot重新编译uboot,由最后一条链接命令开始分析uboot 目录 1.分析start.S 2._start会跳转到start_code处 ...