1 Star 0 Fork 1

sina_woker/dnw

forked from xiaofeng.tan/dnw 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
dnw.c 3.83 KB
一键复制 编辑 原始数据 按行查看 历史
xiaofeng.tan 提交于 2015-09-10 17:23 . first
/*
* This program come form network.
*
* this file implemention U-boot dnw download file to RAM on GNU/Linux system
* dependent on secbulk driver.
*
*/
#include "secbulk.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <error.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif
#ifndef EXIT_FAILURE
#define EXIT_SUCCESS 1
#endif
#define DNW_DEV "/dev/secbulk0"
#define LOAD_ADDR (0x32000000)
#define max(a, b) (a < b ? b : a)
struct dnw_head {
unsigned long load_addr;
unsigned long trans_size;
};
struct dnw {
struct dnw_head head;
int fil_fd;
off_t fil_siz;
int dev_fd;
unsigned short sum; /* transmit checksum */
};
static ssize_t read2write(int read_fd, int write_fd, void *buffer, size_t size) {
ssize_t remain, n;
if ((remain = read(read_fd, buffer, size)) < 0) {
error(0, errno, "Read file error");
return -1;
}
size = remain;
while ((n = write(write_fd, buffer, remain)) != remain) {
if (n < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR)
continue;
else {
error(0, errno, "write data error");
return -1;
}
}
buffer += n;
remain -= n;
}
return size;
}
static int trans_file(int src_fd, struct stat *srcfstat, int dest_fd,
unsigned short *sum) {
int i;
ssize_t n;
unsigned char *buf;
size_t bufsize = max(BULKOUT_BUFFER_SIZE, srcfstat->st_blksize);
size_t transed = 0;
size_t remain = srcfstat->st_size;
if (!(buf = malloc(bufsize))) {
error(0, ENOMEM, "malloc");
return -1;
}
while (remain) {
if ((n = read2write(src_fd, dest_fd, buf, bufsize)) < 0) {
free(buf);
return -1;
}
remain -= n;
transed += n;
printf("\r%.1f%%\t "
#if __SIZEOF_SIZE_T__ == __SIZEOF_INT__
"%u"
#else
"%lu"
#endif
" Bytes", transed / (srcfstat->st_size / 100.0), transed);
fflush(stdout);
/* checksum */
for (i = 0; i < n; i++)
*sum += buf[i];
}
free(buf);
return 0;
}
void usage(int exit_val) {
printf("Usage: dwn <filename>\n");
exit(exit_val);
}
int main(int argc, char* argv[]) {
struct dnw dnw = { .sum = 0 };
if (argc != 2)
usage(EXIT_FAILURE);
if (strncmp(argv[1], "-h", 2) == 0 || strncmp(argv[1], "--help", 6) == 0)
usage(EXIT_SUCCESS);
/* open file */
if ((dnw.fil_fd = open(argv[1], O_RDONLY)) < 0)
error(-1, errno, "Cannot open %s", argv[1]);
printf("File name : %s\n", argv[1]);
/* get file size */
struct stat fil_stat;
if (fstat(dnw.fil_fd, &fil_stat) < 0)
error(-1, errno, "Get file info filed");
dnw.fil_siz = fil_stat.st_size;
printf("File size : %lu(%#lx) Bytes\n", dnw.fil_siz, dnw.fil_siz);
/* open device file */
if ((dnw.dev_fd = open(DNW_DEV, O_WRONLY)) < 0)
error(-1, errno, "Cannot open device %s", DNW_DEV);
dnw.head.load_addr = LOAD_ADDR;
dnw.head.trans_size = sizeof(dnw.head) + dnw.fil_siz + sizeof(dnw.sum);
printf("Transmitting ...\n");
/* transmit head */
if (sizeof(dnw.head) != write(dnw.dev_fd, &dnw.head, sizeof(dnw.head)))
error(-1, errno, "transmit head error");
/* transmit file */
if (trans_file(dnw.fil_fd, &fil_stat, dnw.dev_fd, &dnw.sum) < 0)
exit(EXIT_FAILURE);
printf("\nchecksum:%#x\n", dnw.sum);
/* transmit checksum */
if (sizeof(dnw.sum) != write(dnw.dev_fd, &dnw.sum, sizeof(dnw.sum)))
error(-1, errno, "transmit checksum error");
printf("Done\n");
close(dnw.dev_fd);
close(dnw.fil_fd);
exit(EXIT_SUCCESS);
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C
1
https://gitee.com/lin-binghua/dnw.git
[email protected]:lin-binghua/dnw.git
lin-binghua
dnw
dnw
master

搜索帮助