tuxsavvy / agere_fw_utils (public) (License: Dual BSD 3-clause and GPLv2) (since 2021-02-07) (hash sha1)
Personal fork of https://repo.or.cz/agere_fw_utils.git
List of commits:
Subject Hash Author Date (UTC)
dump_fw posted June 2007 617a0ae960430d0d93a533ac5dffc7b9c07a777a David Kilroy 2008-10-26 14:19:45
Commit 617a0ae960430d0d93a533ac5dffc7b9c07a777a - dump_fw posted June 2007
Author: David Kilroy
Author date (UTC): 2008-10-26 14:19
Committer name: David Kilroy
Committer date (UTC): 2008-10-26 14:19
Parent(s):
Signer:
Signing key:
Signing status: N
Tree: bf978febfac86c491eabd90048af02edaf0c134b
File Lines added Lines deleted
README.dump_fw 33 0
dump_fw.c 258 0
dump_fw.mk 44 0
File README.dump_fw added (mode: 100644) (index 0000000..f752eb0)
1 dump_fw
2 -------
3
4 Program to dump the Agere FW image from a wl_lkm_718 source tree. The
5 firmware image is intended to be used with the orinoco_cs and
6 hermes_dld Linux driver.
7
8 Untar into the wl_lkm_718 directory and run:
9
10 make -f dump_fw.mk
11
12 This will generate two programs, dump_h1_fw and dump_h2_fw which dump
13 the firmware for Hermes I AP+STA and Hermes II AP+STA respectively.
14
15 To use the programs just do:
16
17 ./dump_h1_fw root
18
19 Which will produce root_ap.fw and root_sta.fw, with root replaced by
20 whatever you specified.
21
22 Enjoy,
23
24 Dave Kilroy
25 June 2007.
26
27
28 KNOWN BUGS
29 ----------
30
31 1. Will only work on a little endian machine. Various numbers come out
32 backwards on a big endian machine.
33 2. Compatibility information offset present, but data not output.
File dump_fw.c added (mode: 100644) (index 0000000..d0254dd)
1 /*
2 * Program to link against Agere FW images, and dump contents to
3 * binary files for loading directly by linux drivers.
4 *
5 *
6 */
7
8 /* Output format (LE numbers)
9 *
10 * vers [6] The text HFW and 3 ASCII digits indicating version
11 * headersize [2] Size of header inc vers, headersize and length
12 * entry point [4] NIC address of entry point
13 * blocks [4] Number of blocks (n)
14 * blk_offset [4] Offset to block data
15 * pdr_offset [4] Offset to PDR data
16 * pri_offset [4] Offset to primary plug data
17 * cpt_offset [4] Offset to compatibility data
18 * signature [arb] firmware signature
19 * Block_1
20 * ..
21 * Block_n
22 * Block_term
23 * pda_1
24 * ..
25 * pda_n
26 * pda_term
27 *
28 * Where Block_n is:
29 * addr [4] NIC address to program data
30 * length [2] Number of bytes of data to program
31 * data [arbitrary] Data to program
32 *
33 * block term is:
34 * 0xFFFFFFFF [4] BLOCK_END identifier
35 * 0x0000 [2] zero length
36 *
37 * pda_n is:
38 * id [4] PDA identifier
39 * addr [4] Address to program PDA
40 * len [4] Number of bytes to program
41 *
42 * pda_term
43 * 0x00000000 [4] PDI_END
44 * 0x00000000 [4]
45 * 0x00000000 [4]
46 *
47 * There is more information available in the driver. In particular
48 * whether the block is supposed to be programmed to NV or volatile,
49 * and various flags.
50 *
51 * Apart from the header, the output format is compatible with the
52 * spectrum_cs image. The header is arbitrary.
53 *
54 * TODO: ensure the output is LE, rather than relying on x86 byte orderring
55 */
56
57 #include <stdio.h>
58 #include <stdlib.h>
59 #include <string.h>
60 #include "dhf.h"
61
62 #define AP_SUFFIX "_ap.fw"
63 #define STA_SUFFIX "_sta.fw"
64 #define VERSION "HFW000"
65
66
67 size_t count_blocks(memimage *image)
68 {
69 CFG_PROG_STRCT *p = image->codep;
70 size_t count = 0;
71 while (p->len)
72 {
73 /* Ignore zero data segments which will not be written */
74 if (p->segment_size)
75 count++;
76 p++;
77 }
78 return count;
79 }
80
81 size_t count_pdr(plugrecord *r)
82 {
83 size_t count = 0;
84 if (r)
85 {
86 while (r->code)
87 {
88 count++;
89 r++;
90 }
91 }
92 return count;
93 }
94
95 size_t acc_block_size(memimage *image)
96 {
97 CFG_PROG_STRCT *p = image->codep;
98 size_t len = 0;
99 while (p->len)
100 {
101 if (p->segment_size)
102 len += p->segment_size;
103 p++;
104 }
105 return len;
106 }
107
108 typedef unsigned int u32;
109 typedef unsigned short u16;
110
111 void dump_blocks(FILE* f, memimage *image)
112 {
113 CFG_PROG_STRCT *p = image->codep;
114 u32 end_addr = 0xFFFFFFFFu; /* Agree with spectrum BLOCK_END */
115 u16 end_size = 0u; /* a sensible size that won't screw the reader */
116 while (p->len)
117 {
118 if (p->segment_size)
119 {
120 /* There is data to program in this block */
121 fwrite (&p->nic_addr, 1, sizeof(p->nic_addr), f);
122 fwrite (&p->segment_size, 1, sizeof(p->segment_size), f);
123 fwrite (p->host_addr, 1, p->segment_size, f);
124 }
125 /* else PROG_STOP, entry point command, or terminating block */
126 p++;
127 }
128 fwrite (&end_addr, 1, sizeof(end_addr), f);
129 fwrite (&end_size, 1, sizeof(end_size), f);
130
131 return;
132 }
133
134 void dump_pdr(FILE *f, plugrecord *r)
135 {
136 u32 end = 0u;
137
138 if (!r)
139 goto terminate;
140
141 while (r->code)
142 {
143 fwrite(&r->code, 1, sizeof(r->code), f);
144 fwrite(&r->addr, 1, sizeof(r->addr), f);
145 fwrite(&r->len, 1, sizeof(r->len), f);
146 r++;
147 }
148 terminate:
149 /* Terminate the PDR list */
150 fwrite(&end, 1, sizeof(end), f);
151 fwrite(&end, 1, sizeof(end), f);
152 fwrite(&end, 1, sizeof(end), f);
153 return;
154 }
155
156 void dump_image(FILE* f, memimage *image)
157 {
158 u32 blocks = count_blocks(image);
159 u32 blk_offset = 0; /* Immediately after header */
160 u32 pdr_offset = (acc_block_size(image) +
161 ((blocks + 1) * (sizeof(u32) + sizeof(u16))));
162 u32 pri_offset = pdr_offset +
163 ((count_pdr(image->pdaplug) + 1) * sizeof(u32) * 3);
164 u32 cpt_offset = pri_offset +
165 ((count_pdr(image->priplug) + 1) * sizeof(u32) * 3);
166 u16 headersize = ((sizeof(VERSION)-1) +
167 sizeof(u16) +
168 (sizeof(u32)*6) +
169 sizeof(image->signature));
170
171 fwrite (VERSION, 1, sizeof(VERSION)-1, f);
172 fwrite (&headersize, 1, sizeof(headersize), f);
173 fwrite (&image->execution, 1, sizeof(image->execution), f);
174 fwrite (&blocks, 1, sizeof(blocks), f);
175 fwrite (&blk_offset, 1, sizeof(blk_offset), f);
176 fwrite (&pdr_offset, 1, sizeof(pdr_offset), f);
177 fwrite (&pri_offset, 1, sizeof(pri_offset), f);
178 fwrite (&cpt_offset, 1, sizeof(cpt_offset), f);
179 fwrite (&image->signature, 1, sizeof(image->signature), f);
180
181 dump_blocks(f, image);
182 dump_pdr(f, image->pdaplug);
183 dump_pdr(f, image->priplug);
184 /* compat info not written */
185
186 return;
187 }
188
189 extern memimage ap;
190 extern memimage station;
191
192 int main (int argc, char** argv)
193 {
194 char *ap_filename;
195 char *sta_filename;
196 FILE *ap_file;
197 FILE *sta_file;
198 size_t len;
199 int rc = 0;
200
201 if (argc < 2)
202 {
203 printf("Please specify a root filename.\n"
204 "%s will be appended for primary firmware\n"
205 "%s will be appended for secondary firmaware\n",
206 AP_SUFFIX, STA_SUFFIX);
207 return 1;
208 }
209
210 len = strlen(argv[1]);
211 ap_filename = malloc(len + sizeof(AP_SUFFIX) + 1);
212 if (!ap_filename)
213 {
214 fprintf(stderr, "Out of memory\n");
215 return 1;
216 }
217 strncpy(ap_filename, argv[1], len);
218 ap_filename[len] = 0;
219 strcat(ap_filename, AP_SUFFIX);
220
221 ap_file = fopen(ap_filename, "w");
222 if (!ap_file)
223 {
224 fprintf(stderr, "Can't open %s for writing\n", ap_filename);
225 rc = 1;
226 }
227 else
228 {
229 dump_image(ap_file, &ap);
230 fclose(ap_file);
231 }
232 free(ap_filename);
233
234 sta_filename = malloc(len + sizeof(STA_SUFFIX) + 1);
235 if (!sta_filename)
236 {
237 fprintf(stderr, "Out of memory\n");
238 return 1;
239 }
240 strncpy(sta_filename, argv[1], len);
241 sta_filename[len] = 0;
242 strcat(sta_filename,STA_SUFFIX);
243
244 sta_file = fopen(sta_filename,"w");
245 if (!sta_file)
246 {
247 fprintf(stderr, "Can't open %s for writing\n", sta_filename);
248 rc = 1;
249 }
250 else
251 {
252 dump_image(sta_file, &station);
253 fclose(sta_file);
254 }
255 free(sta_filename);
256
257 return rc;
258 }
File dump_fw.mk added (mode: 100644) (index 0000000..83c9587)
1 #
2 # Makefile for wlags49_cs_xxx
3 #
4
5 LIB := ../lib
6
7 DIR_HCF = hcf
8 DIR_DHF = dhf
9 DIR_FW = dhf
10 DIR_CONFIG = include/hcf
11 DIR_WIRELESS = include/wireless
12
13 CONFIG_HEADERS = $(DIR_CONFIG)/debug.h $(DIR_CONFIG)/hcfcfg.h
14 HCF_HEADERS = $(DIR_HCF)/hcf.h $(DIR_HCF)/mdd.h $(DIR_HCF)/hcfdef.h
15 MMD_HEADERS = $(MMD_DIR)/mmd.h
16 WIRELESS_HEADERS = $(DIR_WIRELESS)/wl_enc.h $(DIR_WIRELESS)/wl_if.h $(DIR_WIRELESS)/wl_internal.h $(DIR_WIRELESS)/wl_version.h
17
18 OBJS = dump_fw.o
19
20 CFLAGS += -O3 -Wall -Wstrict-prototypes -pipe -DHCF_DLV
21 CPPFLAGS +=
22 CC = gcc -I$(DIR_CONFIG) -I$(DIR_HCF) -I$(DIR_DHF)
23
24 H2_OBJS = firmware/ap_h2.o firmware/sta_h2.o
25 H2_CFLAGS = -DHCF_TYPE=4
26
27 H1_OBJS = firmware/ap_h1.o firmware/sta_h1.o
28 H1_CFLAGS = -DHCF_TYPE=0
29
30
31
32 # H1-STAP and H2-STAP are the default targets
33 all: dump_h1_fw dump_h2_fw
34
35 dump_h1_fw : CFLAGS+=$(H1_CFLAGS)
36 dump_h1_fw : $(OBJS) $(H1_OBJS)
37 gcc $(CFLAGS) $^ -o $@
38
39 dump_h2_fw : CFLAGS+=$(H2_CFLAGS)
40 dump_h2_fw : $(OBJS) $(H2_OBJS)
41 gcc $(CFLAGS) $^ -o $@
42
43 clean :
44 rm $(OBJS) $(H1_OBJS) $(H2_OBJS) dump_h1_fw dump_h2_fw
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/tuxsavvy/agere_fw_utils

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/tuxsavvy/agere_fw_utils

Clone this repository using git:
git clone git://git.rocketgit.com/user/tuxsavvy/agere_fw_utils

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main