• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

YK-L1刷机

武飞扬头像
RobinWitch
帮助1

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/Kconfigdrivers/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
系列文章
更多 icon
同类精品
更多 icon
继续加载