YK-L1刷机
1.测试是否能够连接到路由器
插上网线和电脑相连,网线插在路由器那端要插在LAN接口而不是WAN接口,在电脑的设置中找到新增的网络4,
点击下,我们就可以看到它的ip地址是192.168.144.1,在这里和通常的有点区别,比如一般的是192.168.11.1,路由器背后贴图显示地址也是wifi.youku.com,但对我这都没用,我感觉应该是我买的二手路由器已经被刷机过一次了。
然后我们ssh连接试试,成功!
2.刷breed
(这步可以选择不看,因为感觉大多数人的机子都自带了breed,检测是否有breed的方法是:拔出电源,按住路由器reset的键不放,并同时插上电源,继续按个大概5s钟的reset键就可以松手了,把网线一端连接在路由器LAN口一端连接在本机,在本机上输入192.168.1.1
,看有没有breed的页面。)
进入 https://breed.hackpascal.net/
,直接找到对应的编译好的二进制文件,我们的话就是breed-mt7620-youku-yk1.bin
,接下来我们就想把这个文件放到路由器里,一些方法说的是用U盘,但巧了U盘不在我身边,图省事,我就直接在mobaxterm里连接上这个路由器,直接用mobaxterm自带的文件传输搞定。
我们cat /proc/mtd
来看看flash的分区情况
接下来就把breed烧进去,mtd write /tmp/breed-mt7620-youku-yk1.bin u-boot
(PS:这步我其实一直没成功,一开始是显示没有u-boot的权限,无法写入,因为自带的固件openwrt会把u-boot给锁了,有点头疼,但不重要,感觉大家买的机子应该都自带了breed
但刷过一遍padavan后,我又尝试刷刷breed,却又提示我-sh: mtd: not found
,之后发现其实刷过此padavan后原本的mtd的命令是mtd_write,所以用mtd_write write /tmp/breed-mt7620-youku-yk1.bin Bootloader
命令就行了,注意了,刷不同的firmware后mtd分区也有可能发生变化,比如现在就会变成这种样子)
3.Padavan firmware编译
先安装需要的依赖包,本次运行环境是Ubuntu16.04,我知道这版本极度老。。。但是推荐是这样的,我试了试用新的Ubuntu22,但是编译时出现了我无法解决的问题,就乖乖回来Ubuntu16了。
apt-get install language-pack-zh-hans apt-utils gcc g gdb binutils build-essential make bison flex autoconf automake patch gawk bzip2 gettext pkg-config libtool zlib1g-dev libgmp3-dev libmpfr-dev libmpc-dev libreadline-dev vsftpd lrzsz lftp telnet curl astyle exfat-fuse ethtool sysstat bridge-utils p7zip-full help2man libtool-bin libncurses5-dev git gperf texinfo python-docutils mc autopoint
接下来开始做镜像了,复制git仓库,编译所需工具链,编译fireware
git clone https://gitlab.com/padavan-ng/padavan-ng.git
cd padavan-ng/toolchain
sh build_toolchain.sh #编译工具链,这步大概要花20分钟这样子,我是4核CPU
cd ../trunk
cp configs/templates/youku/yk_l1_full.config .config #复制yk-l1的配置文件,已经提供好模板了
sh build_firmware.sh #编译固件,这步大概也要花20分钟这样子
我们会发现在padavan-ng/trunk/images
目录下多了一个YK-L1_3.4.3.9L-100.trx
,这个就是我们想要的固件,把这个文件拷贝到我们本机上。
4.烧板
由于已经刷好breed了,现在更新固件很容易,按住路由器reset的键不放,并同时插上电源,继续按个大概5s钟的reset键就可以松手了。
把网线一端连接在路由器LAN口一端连接在本机,在本机上输入192.168.1.1
进入breed页面,
上传我们刚编译好的镜像,等待烧录即可。
5.验证
待路由器自动重启后,重新进入192.168.1.1
,注意了,初始的用户名和密码均是 admin
欸嘿,成功了!
如若想进入命令行页面的话,可以用telnet连接,使用命令telnet 192.168.1.1
,跟我们熟悉的ssh差不多,但是padavan默认是把ssh关了的,我们也可以开,在Advanced Settings的Administration里把Enable SSH Server改成Yes即可。
杂文
1.1设置应用开机后自启动
比如我们想开机启动一些应用,最简单的方法之一就是开机自动执行一条命令,有些方法是配置/etc/rc.local文件,但是我看了看,ubuntu20和22都没这个文件,即便自己生成了这个文件也还是要一些额外的步骤,有点麻烦,下面给大家介绍一种能用的方法,但是这个方法不能用于pandavan,所以大家看看就行,我主要是自己尝试了怕自己忘记想记录下
1.编写测试用程序
这里自己主要想测试下对文件读取写入类的命令,比如open,read,write之类,就写了一个C程序,目的是生成一个名为fd1的文件,然后将fd1文件复制一下,生成一个内容一模一样,名为fd2的文件。
下面是测试程序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#define N 1024
int main(int argc,char* argv[])
{
char* fd1_path="/home/oslab/Desktop/fd1"; //大家可以把这改成你们想要的路径
char* fd2_path="/home/oslab/Desktop/fd2";
int fd1 = open(fd1_path,O_RDWR|O_CREAT,0777); // 以可读写的权限打开,并当此文件不存在时创建该文件
int fd2 = open(fd2_path,O_RDWR|O_CREAT,0777); // 以可读写的权限打开,并当此文件不存在时创建该文件
if(fd1==-1||fd2==-2)
{
perror("open error");
exit(1);
}
char *hello="hello world!\n";
int str_len=0;
while(hello[str_len]) str_len ; // 读取当前字符串长度
write(fd1,hello,str_len); // 将hello world写入fd1中
//由于文件被写入的原因,此时fd1文件光标在文件尾部,如果直接使用read读取fd1的话会直接显示0
//所以我们有两种方式
//一种是先关闭文件再打开文件,这样的话光标就直接回到文件头了
//方式一
//close(fd1);
//fd1 = open(fd1_path,O_RDWR);
//还有种方式是直接更改当前光标,让它回到文件头的位置
//方式二
lseek(fd1,SEEK_SET,0);
char* buf[N];
int n =0;
// 读取被拷贝文件中的内容
int read_size=read(fd1,buf,str_len);
if(read_size<0)
{
perror("read error");
exit(1);
}
printf("read_size: %d\n",read_size);
// 将复制的fd1的内容写入fd2中
write(fd2,buf,read_size);
close(fd1);
close(fd2);
return 0;
}
2.编写运行脚本
这里我把这个脚本命名为test.sh,测试程序经过gcc编译后生成名为a.out的文件,无论是test.sh还是a.out,都存放在路径为/home/oslab/Desktop的位置中
#!/bin/bash
/home/oslab/Desktop/a.out
3.编写start.service
我们进入 /etc/systemd/system目录下,新建一个test.service文件,内容如下
#**** *.service***
# THIS IS A GENERATED FILE, NOT RECOMMENDED TO EDIT.
[Unit]
Description="startup test service"
After=network.target
[Service]
Type=simple
ExecStart=/bin/bash /home/oslab/Desktop/test.sh
[Install]
WantedBy=multi-user.target
可能有人会想,如若我们把 ExecStart=/bin/bash /home/oslab/Desktop/test.sh
直接修改为ExecStart=/bin/bash /home/oslab/Desktop/a.out,那岂不是可以不用第二步的编写运行脚本了么?但我试了试,很可悲的失败了,估计这里只能执行脚本而不能直接填命令
4.设置为开机自启动
下面简单介绍下三条命令
sudo systemctl enable test.service
sudo systemctl start test.service
sudo systemctl status test.service
enable是用于开机自启动的,start是用于现在就立刻启动的,status是用来看这个service状态的,可以用来看这个文件的输出
5.验证
正常情况下,重启下机子,就能看到桌面上多了fd1和fd2这两个文件了,实验成功。
1.2内核模块编写(使用insmod方式)
众所周知,每一个新程序新语言第一步都是从helloworld开始,我们先写一个test.c输出helloworld叭
//test.c
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
MODULE_LICENSE("GPL");
int init_module()
{
printk(KERN_INFO "init_module hello world!\n");
return 0;
}
void cleanup_module()
{
printk(KERN_INFO "cleanup_module hello world!\n");
}
这里init_module是这个内核模块(就是这个test)被刚插入(insmod)时执行的,cleanup_module是内核模块在被卸除的时候执行的。
接下来为了生成这个内核文件,我们要写个makefile
KERNELDIR ?=/lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
obj-m := test.o
all:
make -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mode.c .tmp_versions *.mod *.order *.symvers
这里这个 make -C $(KERNELDIR)
指明跳转到源码目录下读取那里的Makefile;M=$(PWD)
表明然后返回到当前目录继续读入、执行当前的Makefile。
而后我们就能在目录下面看到这个test.ko了
然后我们依次输入
sudo insmod test.ko #插入模块
sudo rmmod test #移除模块
sudo dmesg #显示内核日志
就可以看到如下满意的结果
1.3内核模块编写(跟随内核一起编译)
虽说上述方式可以插入内核模块,但是总感觉差点意思,比如,每次重启一遍就得重新插入一遍(这个弊端可以通过设置开机启动解决),最关键的事,感觉不像原生内核模块一样,我们想要的是内核模块跟着原本的内核一起编译结合为一体,这样才感觉比较有意思。
我们进入padavan-ng/trunk/linux-3.4.x/drivers#
目录下,这是驱动目录,也是我们下面主要进行操作的目录
完成下需要的文件结构
mkdir hello #新建一个hello文件夹
cd hello
touch Kconfig Makefile hello.c
Kconfig
menu "hello KM"
comment "hello kernel module"
config HELLO
tristate "hello module"
default y
help
hello kernel module test
endmenu
Makefile
obj-${CONFIG_HELLO} = hello.o
hello.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/ktime.h>
#include <linux/kthread.h>
#include <linux/delay.h>
static struct task_struct *ht = NULL;
static int thread_hello(void *para)
{
int i = 0;
while(!kthread_should_stop())
{
printk(KERN_DEBUG "cbh thread run, %d\n", i );
msleep(1000);
}
return 0;
}
static int __init hello_init(void)
{
printk(KERN_DEBUG "hello, cbh\n");
ht = kthread_run(thread_hello, NULL, "hello_thread");
if(NULL == ht)
{
printk(KERN_ERR "kernel thread create failed\n");
return -1;
}
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_DEBUG "bye, cbh\n");
if(NULL != ht)
{
kthread_stop(ht);
}
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("cbh");
MODULE_DESCRIPTION("TEST in kernel source");
接下来我们来修改 drivers/Kconfig 和 drivers/Makefile
在 driver/Kconfig 中添加 source "drivers/hello/Kconfig
在 driver/Makefile 中添加 obj-${CONFIG_HELLO} = hello/
至此,添加内核模块便大功告成了,我们可以返回到 3.Padavan firmware编译进行编译。
最后我们上板检验,照例使用命令dmesg
查查系统日志,欸嘿成功了
1.4应用模块编写
编写这的主要原因是,我们一般不会在像路由器这些设备上编译程序,因为这样的话要多安装一个gcc,gcc很大,这样不好,所以编译固件的时候也顺便把应用编译了。
在这里其实跟内核模块编写差距不大,我们还是延续这1.1和1.3的思路,只不过这回我们还是在trunk/user
目录下进行操作,下面是需要的文件目录结构
mkdir test #新建一个hello文件夹
cd test
touch Makefile test.c
其中test.c内容如下,跟1.1一样
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#define N 1024
int main(int argc,char* argv[])
{
char* fd1_path="/home/root/fd1"; //大家可以把这改成你们想要的路径
char* fd2_path="/home/root/fd2";
int fd1 = open(fd1_path,O_RDWR|O_CREAT,0777); // 以可读写的权限打开,并当此文件不存在时创建该文件
int fd2 = open(fd2_path,O_RDWR|O_CREAT,0777); // 以可读写的权限打开,并当此文件不存在时创建该文件
if(fd1==-1||fd2==-2)
{
perror("open error");
exit(1);
}
char *hello="hello world!\n";
int str_len=0;
while(hello[str_len]) str_len ; // 读取当前字符串长度
write(fd1,hello,str_len); // 将hello world写入fd1中
//由于文件被写入的原因,此时fd1文件光标在文件尾部,如果直接使用read读取fd1的话会直接显示0
//所以我们有两种方式
//一种是先关闭文件再打开文件,这样的话光标就直接回到文件头了
//方式一
//close(fd1);
//fd1 = open(fd1_path,O_RDWR);
//还有种方式是直接更改当前光标,让它回到文件头的位置
//方式二
lseek(fd1,SEEK_SET,0);
char* buf[N];
int n =0;
// 读取被拷贝文件中的内容
int read_size=read(fd1,buf,str_len);
if(read_size<0)
{
perror("read error");
exit(1);
}
printf("read_size: %d\n",read_size);
// 将复制的fd1的内容写入fd2中
write(fd2,buf,read_size);
close(fd1);
close(fd2);
return 0;
}
Makefile内容如下
test:test.c
$(CC) -o test test.c
romfs:
$(ROMFSINST) test /bin/test
注意前缀空格是Tab符号而不是空格,可能有人会奇怪,明明$(CC)
和$(ROMFSINST)
都没定义啊,为啥能用?因为这个Makefile在固件编译过程中是逐层调用的,上层的Makefile已经定义好了如CC这些变量,比如这里CC就是交叉编译的变量,值为/root/padavan-ng/trunk/../toolchain/out/bin/mipsel-linux-uclibc-gcc -mips32r2 -march=mips32r2 -mtune=24kec
但这里romfs的作用我不太清楚,只不过这里romfs的作用就是在/bin下生成test的可执行文件,只有这样才能运行成功,如果不加的话,虽说在/usr/bin下也能找得到test,但是这个test却无法执行,我有点奇怪,不怎么清楚原因。
最后我们回到上层目录trunk/user
下,更新下Makefile文件,加上dir_y = test
,让Makefile能够知道识别我们还写了个test的应用模块,并且把它编译好。
以上应用模块就编写完了。
回到我们的trunk目录下,执行下sh build_firmware.sh
的编译固件命令,还是按着之前步骤进行烧板,运行test检测。
如下图,这样运行成功啦,有read_size:13的输出,有fd1,fd2的文件生成
但是这样在/usr/bin下和/bin/busubox执行test,都无法成功,很奇怪,个人表示无法理解
参考资料
最新版本breed下载地址
AR/QCA/MTK Breed,功能强大的多线程 Bootloader (这个是breed作者的更新贴)
Linux kernel:如何向内核中添加自定义内核模块
ubuntu开机自启动(绝对好用)
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgkiaah
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13