Some time ago I've written the letter to [EMAIL PROTECTED] about reiser4 support in GNU GRUB and adding memory management to it. As I still have not an answer, I write it one more time. And I hope to receive it this time.
Reiser4 team is interested in adding reiser4 support to GNU GRUB. And it can be done by means of using our static libreiser4, built in stand alone mode, that is, without libc, gcc built-ins and without features which are not needed for GRUB like file creating/writing, repair stuff, etc.
But the problem is that, we use malloc() and free() for memory allocation and cannot use memory working schema addopted by GRUB (one big static array, which is used by all fs-implementations for their memory needs).
And we have written small and simple memory manager for solving this problem. By now we can use it by means of calling not real malloc(), free() functions, but rather some wrappers for instance, aal_malloc(), aal_free(), which call actual memory allocation functions like the following piece of pseudo code shows:
Memory allocation related stuff in Libreiser4:
/* Types for malloc and free handler */ void *(*malloc_handler_t) (int); void (*free_handler_t) (void *);
/* Actual current handlers are stored here */ malloc_handler_t malloc_handler = NULL; free_handler_t free_handler = NULL;
/* Memory allocation handlers setup functions */ void aal_set_malloc_handler(malloc_handler_t handler) { malloc_handler = handler; }
void aal_set_free_handler(free_handler_t handler) { free_handler = handler; }
/* Wrapper functions libreiser4 calls them for its memory needs */ void *aal_malloc(int size) { if (!malloc_handler) retrun NULL;
return malloc_handler(size) }
void aal_free(void *ptr) { if (!free_handler) retrun;
free_handler(ptr) }
/* Example of using aal_malloc durring filesystem opening */ reiser4_fs_t *reiser4_fs_open(aal_device_t *dev) { reiser4_fs_t *fs;
/* Calling memory allocation. In fact malloc_handler() will be called here */
if (!(fs = aal_malloc(sizeof(*dev))))
return NULL;
/* Here is the rest of stuff for initializing fs instance */
return fs; }
Now reiser4 implementation stuff in GRUB:
#define ENABLE_ALONE #include <reiser4/reiser4.h>
/* GRUB specific device methods */ static errno_t grub_dev_read( aal_device_t *device, void *buff, blk_t block, count_t count) { int factor = device->blocksize >> aal_log2(SECTOR_SIZE);
return !devread(block << aal_log2(factor), 0, count * device->blocksize, buff); }
static count_t grub_dev_len(aal_device_t *device) { int factor = device->blocksize >> aal_log2(SECTOR_SIZE); return part_length >> aal_log2(factor); }
/*
Initializing grub device abstraction operations. It will use devread and friends
for providing needed functionality.
*/
struct aal_device_ops grub_dev_ops = {
.read = grub_dev_read,
.len = grub_dev_len
};
/* Reiser4 related grobal variables: opened filesystem, device and current file. */ static int initialized = 0; static reiser4_fs_t *fs = NULL; static reiser4_file_t *file = NULL; static aal_device_t *dev = NULL;
/* Actual memory allocation/release functions which operate on FSYS_BUF */ static void *__chunk_alloc(unsigned int size) { /* Some stuff about allocation memory chunk of requested size */ }
static void __chunk_free(void *ptr) { /* Some stuff about releasing memory chunk pointed by @ptr */ }
/* Initializing reiser4 support */
int reiser4_init() {
void *area_ptr = ((void *)FSYS_BUF);
unsigned int area_len = FSYS_BUFLEN;
/*
Initializing memory manager area by means of initializing first chunk as
NOT USED and (area_len - sizeof(chunk_t)) size long.
*/
first = __chunk_init(area_ptr, area_len - sizeof(chunk_t),
CHUNK_FREE, area_ptr, area_ptr);
/* Initializing memory allocation/deallocation handlers */ aal_set_free_handler(__chunk_free); aal_set_malloc_handler(__chunk_alloc);
/* Initializing libreiser4 itself (initializing plugins, etc) */ return !libreiser4_init(); }
static void reiser4_fini(void) { libreiser4_fini(); }
/* Reiser4 mount() method implementation */ int reiser4_mount(void) { int res;
if (initialized)
return 1;
if (!(res = reiser4_init()))
return res;
if (!(dev = aal_device_open(&grub_dev_ops, NULL,
BLOCKSIZE, 0)))
{
aal_exception_error("Can't open grub device.");
goto error_free_libreiser4;
}
if (!(fs = reiser4_fs_open(dev, NULL))) {
aal_exception_error("Can't open reiser4 filesystem.");
goto error_free_dev;
}
if (!(fs->tree = reiser4_tree_init(fs)))
goto error_free_fs;
initialized = 1;
return 1;
error_free_fs: reiser4_fs_close(fs); fs = NULL; error_free_dev: aal_device_close(dev); dev = NULL; error_free_libreiser4: libreiser4_fini(); return 0; }
/* close() implementation */
void reiser4_close(void) {
if (file != NULL) {
reiser4_file_close(file);
file = NULL;
}
if (fs != NULL) {
reiser4_fs_close(fs);
fs = NULL;
}
if (dev != NULL) { aal_device_close(dev); dev = NULL; }
reiser4_fini(); initialized = 0; }
/* read() implementation */
int reiser4_read(char *buf, int len) {
if (file == NULL)
return 0;
if (filepos == 0) {
if (reiser4_file_reset(file))
return 0;
}
if (reiser4_file_read(file, buf, len) == 0)
return 0;
filepos = reiser4_file_offset(file); return 1; }
/* dir() method implementation */ int reiser4_dir(char *dirname) { ... }
And now the problem is that, we cannot use FSYS_BUF for memory manager, because it is used by all fs GRUB supports them and as they are not aware about the memory manager, they work with FSYS_BUF as with dedicated to them raw data array and corrupt it.
Actually it make sence only for running GRUB in usual enviromnent when it has active all fs-implementations and call them one by one durring attampt_mount().
In boot time everything probably will be okay, as GRUB will use only one fs-implemntation and namely root partition uses it, say reiser4. But as "memory manager tack" exists in GRUB's TODO list, probably it is time to implement it?
So, as a summary, possible solutions are:
(1) Use the memory manager in all GRUB components instead of using static array.
(2) Allocate another buffer dedicated to reiser4 private purposes (and namely for memory manager)
(3) ???
What do you think about it?
-- Yury Umanets
_______________________________________________ Bug-grub mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-grub